<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="keywords" content="玖忆;文鹤;博客">
    
    <meta name="author" content="meteor">
    <!-- preconnect -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    
    
    <!--- Seo Part-->
    
    <link rel="canonical" href="https://wait-you.github.io/2023/06/02/rabbitmq/"/>
    <meta name="robots" content="index,follow">
    <meta name="googlebot" content="index,follow">
    <meta name="revisit-after" content="1 days">
    
        <meta name="description" content="# 1. 消息中间件概述 # 1.1. 什么是消息中间件 MQ 全称为 Message Queue，消息队列是应用程序和应用程序之间的通信方法。   为什么使用 MQ 在项目中，可将一些无需即时返回且耗时的操作提取出来，进行异步处理，而这种异步处理的方式大大的节省了服务器的请求响应时间，从而提高了系统的吞吐量。   开发中消息队列通常有如下应用场景： 1、任务异步处理 将不需要同步处理的并且耗时长">
<meta property="og:type" content="article">
<meta property="og:title" content="RabbitMQ">
<meta property="og:url" content="https://wait-you.github.io/2023/06/02/RabbitMQ/index.html">
<meta property="og:site_name" content="玖忆">
<meta property="og:description" content="# 1. 消息中间件概述 # 1.1. 什么是消息中间件 MQ 全称为 Message Queue，消息队列是应用程序和应用程序之间的通信方法。   为什么使用 MQ 在项目中，可将一些无需即时返回且耗时的操作提取出来，进行异步处理，而这种异步处理的方式大大的节省了服务器的请求响应时间，从而提高了系统的吞吐量。   开发中消息队列通常有如下应用场景： 1、任务异步处理 将不需要同步处理的并且耗时长">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/01.jpg">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/02.jpg">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/03.jpg">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1555988678324.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1558319510387.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1558319546688.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556006638979.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556006647177.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1555991074575.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1565105223969.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/%E7%94%9F%E4%BA%A7%E8%80%85%E6%B5%81%E8%BD%AC%E8%BF%87%E7%A8%8B%E5%9B%BE.bmp">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/%E6%B6%88%E8%B4%B9%E8%80%85%E6%B5%81%E8%BD%AC%E8%BF%87%E7%A8%8B%E5%9B%BE.bmp">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556009144848.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556014310859.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556014318106.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556014499573.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556010329032.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556015006220.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556029284397.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556031175744.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556031362048.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556031519931.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556032433333.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1565149342994.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1565144326498.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1565149374831.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1565144775216.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1558321303612.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1558321417385.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1558322109359.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1558322192435.png">
<meta property="og:image" content="http://tuchuang.wenhe9.cn/1556074827222.png">
<meta property="article:published_time" content="2023-06-01T20:37:34.000Z">
<meta property="article:modified_time" content="2023-06-05T08:14:13.577Z">
<meta property="article:author" content="meteor">
<meta property="article:tag" content="RabbitMQ">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://tuchuang.wenhe9.cn/01.jpg">
    
    
    <!--- Icon Part-->
    <link rel="icon" type="image/png" href="/images/wenhe.png" sizes="192x192">
    <link rel="apple-touch-icon" sizes="180x180" href="/images/wenhe.png">
    <meta name="theme-color" content="#f1404b">
    <link rel="shortcut icon" href="/images/wenhe.png">
    <!--- Page Info-->
    
    <title>
        
            RabbitMQ -
        
        玖忆
    </title>
    
<link rel="stylesheet" href="/css/style.css">

    
<link rel="stylesheet" href="/assets/fonts.css">

    <!--- Font Part-->
    
    
    
    

    <!--- Inject Part-->
    
    <script id="hexo-configurations">
    let Global = window.Global || {};
    Global.hexo_config = {"hostname":"wait-you.github.io","root":"/","language":"zh-CN"};
    Global.theme_config = {"articles":{"style":{"font_size":"16px","line_height":1.5,"image_border_radius":"14px","image_alignment":"center","image_caption":false,"link_icon":true},"word_count":{"enable":true,"count":true,"min2read":true},"author_label":{"enable":true,"auto":false,"list":[]},"code_block":{"copy":true,"style":"mac","font":{"enable":false,"family":null,"url":null}},"toc":{"enable":true,"max_depth":3,"number":false,"expand":true,"init_open":true},"copyright":true,"lazyload":true,"recommendation":{"enable":false,"title":"推荐阅读","limit":3,"placeholder":"http://tuchuang.wenhe9.cn/default-bg.jpg","skip_dirs":[]}},"colors":{"primary":"#f1404b","secondary":null},"global":{"fonts":{"chinese":{"enable":false,"family":null,"url":null},"english":{"enable":false,"family":null,"url":null}},"content_max_width":"1000px","sidebar_width":"210px","hover":{"shadow":true,"scale":false},"scroll_progress":{"bar":true,"percentage":true},"busuanzi_counter":{"enable":true,"site_pv":true,"site_uv":true,"post_pv":true},"pjax":true,"open_graph":true,"google_analytics":{"enable":false,"id":null}},"home_banner":{"enable":true,"style":"static","image":{"light":"http://tuchuang.wenhe9.cn/default-bg.jpg","dark":"http://tuchuang.wenhe9.cn/default-bg.jpg"},"title":"玖忆","subtitle":{"text":["我本微末凡尘、可也心向天空"],"hitokoto":{"enable":false,"api":"https://v1.hitokoto.cn"},"typing_speed":100,"backing_speed":80,"starting_delay":500,"backing_delay":1500,"loop":true,"smart_backspace":true},"text_color":{"light":"#fff","dark":"#d1d1b6"},"text_style":{"title_size":"2.8rem","subtitle_size":"1.5rem","line_height":1.2},"custom_font":{"enable":false,"family":null,"url":null},"social_links":{"enable":true,"links":{"github":"https://gitee.com/du-jinliang","instagram":null,"zhihu":null,"twitter":null,"email":"dujinliang9@163.com"}}},"plugins":{"feed":{"enable":false},"aplayer":{"enable":false,"type":"fixed","audios":[{"name":null,"artist":null,"url":null,"cover":null}]},"mermaid":{"enable":false,"version":"9.3.0"}},"version":"2.1.4","navbar":{"auto_hide":true,"color":{"left":"#f78736","right":"#367df7","transparency":35},"links":{"Home":{"path":"/","icon":"fa-regular fa-house"}},"search":{"enable":false,"preload":true}},"page_templates":{"friends_column":2,"tags_style":"blur"},"home":{"sidebar":{"enable":true,"position":"left","first_item":"menu","announcement":null,"links":null},"article_date_format":"auto","categories":{"enable":true,"limit":3},"tags":{"enable":true,"limit":3}}};
    Global.language_ago = {"second":"%s 秒前","minute":"%s 分钟前","hour":"%s 小时前","day":"%s 天前","week":"%s 周前","month":"%s 个月前","year":"%s 年前"};
    Global.data_config = {"masonry":false};
  </script>
    
    <!--- Fontawesome Part-->
    
<link rel="stylesheet" href="/fontawesome/fontawesome.min.css">

    
<link rel="stylesheet" href="/fontawesome/brands.min.css">

    
<link rel="stylesheet" href="/fontawesome/solid.min.css">

    
<link rel="stylesheet" href="/fontawesome/regular.min.css">

    
    
    
    
<meta name="generator" content="Hexo 6.3.0"></head>


<body>
<div class="progress-bar-container">
    
        <span class="scroll-progress-bar"></span>
    

    
        <span class="pjax-progress-bar"></span>
        <span class="pjax-progress-icon">
            <i class="fa-solid fa-circle-notch fa-spin"></i>
        </span>
    
</div>


<main class="page-container">

    

    <div class="main-content-container">

        <div class="main-content-header">
            <header class="navbar-container">
    
    <div class="navbar-content">
        <div class="left">
            
            <a class="logo-title" href="/">
                
                玖忆
                
            </a>
        </div>

        <div class="right">
            <!-- PC -->
            <div class="desktop">
                <ul class="navbar-list">
                    
                        
                            <li class="navbar-item">
                                <!-- Menu -->
                                <a class="" 
                                    href="/"  >
                                    
                                        
                                            <i class="fa-regular fa-house"></i>
                                        
                                        首页
                                    
                                </a>
                                <!-- Submenu -->
                                
                            </li>
                    
                    
                </ul>
            </div>
            <!-- Mobile -->
            <div class="mobile">
                
                <div class="icon-item navbar-bar">
                    <div class="navbar-bar-middle"></div>
                </div>
            </div>
        </div>
    </div>

    <!-- Mobile drawer -->
    <div class="navbar-drawer">
        <ul class="drawer-navbar-list">
            
                
                    <li class="drawer-navbar-item flex-center">
                        <a class="" 
                        href="/"  >
                             
                                
                                    <i class="fa-regular fa-house"></i>
                                
                                首页
                            
                        </a>
                    </li>
                    <!-- Submenu -->
                    
            

        </ul>
    </div>

    <div class="window-mask"></div>

</header>


        </div>

        <div class="main-content-body">

            

            <div class="main-content">

                
                    <div class="fade-in-down-animation">
    <div class="post-page-container">
        <div class="article-content-container">

            
            
                <div class="article-title">
                    <h1 class="article-title-regular">RabbitMQ</h1>
                </div>
            
                
            

            
                <div class="article-header">
                    <div class="avatar">
                        <img src="/images/wenhe.png">
                    </div>
                    <div class="info">
                        <div class="author">
                            <span class="name">meteor</span>
                            
                                <span class="author-label">Lv3</span>
                            
                        </div>
                        <div class="meta-info">
                            <div class="article-meta-info">
    <span class="article-date article-meta-item">
        <i class="fa-regular fa-pen-fancy"></i>&nbsp;
        <span class="desktop">2023-06-01 12:37:34</span>
        <span class="mobile">2023-06-01 12:37</span>
        <span class="hover-info">创建</span>
    </span>
    
        <span class="article-date article-meta-item">
            <i class="fa-regular fa-wrench"></i>&nbsp;
            <span class="desktop">2023-06-05 00:14:13</span>
            <span class="mobile">2023-06-05 00:14</span>
            <span class="hover-info">更新</span>
        </span>
    

    
        <span class="article-categories article-meta-item">
            <i class="fa-regular fa-folders"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/categories/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/">消息中间件</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    
    
        <span class="article-tags article-meta-item">
            <i class="fa-regular fa-tags"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/tags/RabbitMQ/">RabbitMQ</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    

    
    
    
    
        <span class="article-pv article-meta-item">
            <i class="fa-regular fa-eye"></i>&nbsp;<span id="busuanzi_value_page_pv"></span>
        </span>
    
</div>

                        </div>
                    </div>
                </div>
            

            <div class="article-content markdown-body">
                <h1 id="1-消息中间件概述"><a class="markdownIt-Anchor" href="#1-消息中间件概述">#</a> 1. 消息中间件概述</h1>
<h2 id="11-什么是消息中间件"><a class="markdownIt-Anchor" href="#11-什么是消息中间件">#</a> 1.1. 什么是消息中间件</h2>
<p>MQ 全称为 Message Queue，消息队列是应用程序和应用程序之间的通信方法。</p>
<ul>
<li>
<p>为什么使用 MQ</p>
<p>在项目中，可将一些无需即时返回且耗时的操作提取出来，进行<strong>异步处理</strong>，而这种异步处理的方式大大的节省了服务器的请求响应时间，从而<strong>提高</strong>了<strong>系统</strong>的<strong>吞吐量</strong>。</p>
</li>
<li>
<p>开发中消息队列通常有如下应用场景：</p>
<p>1、任务<strong>异步</strong>处理</p>
<p>将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。</p>
<p>2、应用程序<strong>解耦合</strong></p>
<p>MQ 相当于一个中介，生产方通过 MQ 与消费方交互，它将应用程序进行解耦合。</p>
<p>3、<strong>削峰填谷</strong></p>
<p>如订单系统，在下单的时候就会往数据库写数据。但是数据库只能支撑每秒 1000 左右的并发写入，并发量再高就容易宕机。低峰期的时候并发也就 100 多个，但是在高峰期时候，并发量会突然激增到 5000 以上，这个时候数据库肯定卡死了。</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/01.jpg"
                      alt=""
                ></p>
<p>消息被 MQ 保存起来了，然后系统就可以按照自己的消费能力来消费，比如每秒 1000 个数据，这样慢慢写入数据库，这样就不会卡死数据库了。</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/02.jpg"
                      alt=""
                ></p>
<p>但是使用了 MQ 之后，限制消费消息的速度为 1000，但是这样一来，高峰期产生的数据势必会被积压在 MQ 中，高峰就被 “削” 掉了。但是因为消息积压，在高峰期过后的一段时间内，消费消息的速度还是会维持在 1000QPS，直到消费完积压的消息，这就叫做 “填谷”</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/03.jpg"
                      alt=""
                ></p>
</li>
</ul>
<h2 id="12-amqp-和-jms"><a class="markdownIt-Anchor" href="#12-amqp-和-jms">#</a> 1.2. AMQP 和 JMS</h2>
<p>MQ 是消息通信的模型；实现 MQ 的大致有两种主流方式：AMQP、JMS。</p>
<h3 id="121-amqp"><a class="markdownIt-Anchor" href="#121-amqp">#</a> 1.2.1. AMQP</h3>
<p>AMQP 是一种协议，更准确的说是一种 binary wire-level protocol（链接协议）。这是其和 JMS 的本质差别，AMQP 不从 API 层进行限定，而是直接定义网络交换的数据格式。</p>
<h3 id="122-jms"><a class="markdownIt-Anchor" href="#122-jms">#</a> 1.2.2. JMS</h3>
<p>JMS 即 Java 消息服务（JavaMessage Service）应用程序接口，是一个 Java 平台中关于面向消息中间件（MOM）的 API，用于在两个应用程序之间，或分布式系统中发送消息，进行异步通信。</p>
<h3 id="123-amqp-与-jms-区别"><a class="markdownIt-Anchor" href="#123-amqp-与-jms-区别">#</a> 1.2.3. AMQP 与 JMS 区别</h3>
<ul>
<li>JMS 是定义了统一的接口，来对消息操作进行统一；AMQP 是通过规定协议来统一数据交互的格式</li>
<li>JMS 限定了必须使用 Java 语言；AMQP 只是协议，不规定实现方式，因此是跨语言的。</li>
<li>JMS 规定了两种消息模式；而 AMQP 的消息模式更加丰富</li>
</ul>
<h2 id="13-消息队列产品"><a class="markdownIt-Anchor" href="#13-消息队列产品">#</a> 1.3. 消息队列产品</h2>
<p>市场上常见的消息队列有如下：</p>
<ul>
<li>ActiveMQ：基于 JMS</li>
<li>ZeroMQ：基于 C 语言开发</li>
<li>RabbitMQ：基于 AMQP 协议，erlang 语言开发，稳定性好</li>
<li>RocketMQ：基于 JMS，阿里巴巴产品</li>
<li>Kafka：类似 MQ 的产品；分布式消息系统，高吞吐量</li>
</ul>
<h2 id="14-rabbitmq"><a class="markdownIt-Anchor" href="#14-rabbitmq">#</a> 1.4. RabbitMQ</h2>
<p>RabbitMQ 是由 erlang 语言开发，基于 AMQP（Advanced Message Queue 高级消息队列协议）协议实现的消息队列，它是一种应用程序之间的通信方法，消息队列在分布式系统开发中应用非常广泛。</p>
<p>RabbitMQ 官方地址：<a class="link"   target="_blank" rel="noopener" href="http://www.rabbitmq.com/" >http://www.rabbitmq.com/ <i class="fa-regular fa-arrow-up-right-from-square fa-sm"></i></a></p>
<p>RabbitMQ 提供了 6 种模式：简单模式，work 模式，Publish/Subscribe 发布与订阅模式，Routing 路由模式，Topics 主题模式，RPC 远程调用模式（远程调用，不太算 MQ；暂不作介绍）；</p>
<p>官网对应模式介绍：<a class="link"   target="_blank" rel="noopener" href="https://www.rabbitmq.com/getstarted.html" >https://www.rabbitmq.com/getstarted.html <i class="fa-regular fa-arrow-up-right-from-square fa-sm"></i></a></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1555988678324.png"
                      alt="1555988678324"
                ></p>
<h1 id="2-安装及配置rabbitmq"><a class="markdownIt-Anchor" href="#2-安装及配置rabbitmq">#</a> 2. 安装及配置 RabbitMQ</h1>
<p>详细查看  <code>资料/软件/安装RabbitMQ.md</code>  文档。</p>
<h1 id="3-rabbitmq入门"><a class="markdownIt-Anchor" href="#3-rabbitmq入门">#</a> 3. RabbitMQ 入门</h1>
<h2 id="31-搭建示例工程"><a class="markdownIt-Anchor" href="#31-搭建示例工程">#</a> 3.1. 搭建示例工程</h2>
<h3 id="311-创建工程"><a class="markdownIt-Anchor" href="#311-创建工程">#</a> 3.1.1. 创建工程</h3>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1558319510387.png"
                      alt="1555991321159"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1558319546688.png"
                      alt="1555991353704"
                ></p>
<h3 id="312-添加依赖"><a class="markdownIt-Anchor" href="#312-添加依赖">#</a> 3.1.2. 添加依赖</h3>
<p>往 heima-rabbitmq 的 pom.xml 文件中添加如下依赖：</p>
<div class="highlight-container" data-rel="Xml"><figure class="iseeu highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.rabbitmq<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>amqp-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.6.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure></div>
<h2 id="32-编写生产者"><a class="markdownIt-Anchor" href="#32-编写生产者">#</a> 3.2. 编写生产者</h2>
<p>编写消息生产者 com.itheima.rabbitmq.simple.Producer</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.simple;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Channel;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Connection;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.ConnectionFactory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Producer</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">QUEUE_NAME</span> <span class="operator">=</span> <span class="string">&quot;simple_queue&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="comment">//创建连接工厂</span></span><br><span class="line">        <span class="type">ConnectionFactory</span> <span class="variable">connectionFactory</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ConnectionFactory</span>();</span><br><span class="line">        <span class="comment">//主机地址;默认为 localhost</span></span><br><span class="line">        connectionFactory.setHost(<span class="string">&quot;localhost&quot;</span>);</span><br><span class="line">        <span class="comment">//连接端口;默认为 5672</span></span><br><span class="line">        connectionFactory.setPort(<span class="number">5672</span>);</span><br><span class="line">        <span class="comment">//虚拟主机名称;默认为 /</span></span><br><span class="line">        connectionFactory.setVirtualHost(<span class="string">&quot;/itcast&quot;</span>);</span><br><span class="line">        <span class="comment">//连接用户名；默认为guest</span></span><br><span class="line">        connectionFactory.setUsername(<span class="string">&quot;heima&quot;</span>);</span><br><span class="line">        <span class="comment">//连接密码；默认为guest</span></span><br><span class="line">        connectionFactory.setPassword(<span class="string">&quot;heima&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建连接</span></span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> connectionFactory.newConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(QUEUE_NAME, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 要发送的信息</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">message</span> <span class="operator">=</span> <span class="string">&quot;你好；小兔子！&quot;</span>;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：交换机名称，如果没有指定则使用默认Default Exchage</span></span><br><span class="line"><span class="comment">         * 参数2：路由key,简单模式可以传递队列名称</span></span><br><span class="line"><span class="comment">         * 参数3：消息其它属性</span></span><br><span class="line"><span class="comment">         * 参数4：消息内容</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicPublish(<span class="string">&quot;&quot;</span>, QUEUE_NAME, <span class="literal">null</span>, message.getBytes());</span><br><span class="line">        System.out.println(<span class="string">&quot;已发送消息：&quot;</span> + message);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        channel.close();</span><br><span class="line">        connection.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<p>在执行上述的消息发送之后；可以登录 rabbitMQ 的管理控制台，可以发现队列和其消息：</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556006638979.png"
                      alt="1556006638979"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556006647177.png"
                      alt="1556006647177"
                ></p>
<h2 id="33-编写消费者"><a class="markdownIt-Anchor" href="#33-编写消费者">#</a> 3.3. 编写消费者</h2>
<p>抽取创建 connection 的工具类 com.itheima.rabbitmq.util.ConnectionUtil；</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.util;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Connection;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.ConnectionFactory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConnectionUtil</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> Connection <span class="title function_">getConnection</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="comment">//创建连接工厂</span></span><br><span class="line">        <span class="type">ConnectionFactory</span> <span class="variable">connectionFactory</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ConnectionFactory</span>();</span><br><span class="line">        <span class="comment">//主机地址;默认为 localhost</span></span><br><span class="line">        connectionFactory.setHost(<span class="string">&quot;localhost&quot;</span>);</span><br><span class="line">        <span class="comment">//连接端口;默认为 5672</span></span><br><span class="line">        connectionFactory.setPort(<span class="number">5672</span>);</span><br><span class="line">        <span class="comment">//虚拟主机名称;默认为 /</span></span><br><span class="line">        connectionFactory.setVirtualHost(<span class="string">&quot;/itcast&quot;</span>);</span><br><span class="line">        <span class="comment">//连接用户名；默认为guest</span></span><br><span class="line">        connectionFactory.setUsername(<span class="string">&quot;heima&quot;</span>);</span><br><span class="line">        <span class="comment">//连接密码；默认为guest</span></span><br><span class="line">        connectionFactory.setPassword(<span class="string">&quot;heima&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建连接</span></span><br><span class="line">        <span class="keyword">return</span> connectionFactory.newConnection();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<p>编写消息的消费者 com.itheima.rabbitmq.simple.Consumer</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.simple;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.QUEUE_NAME, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="comment">//路由key</span></span><br><span class="line">                System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                <span class="comment">//交换机</span></span><br><span class="line">                System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                <span class="comment">//消息id</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                <span class="comment">//收到的消息</span></span><br><span class="line">                System.out.println(<span class="string">&quot;接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.QUEUE_NAME, <span class="literal">true</span>, consumer);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//不关闭资源，应该一直监听消息</span></span><br><span class="line">        <span class="comment">//channel.close();</span></span><br><span class="line">        <span class="comment">//connection.close();</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<h2 id="34-小结"><a class="markdownIt-Anchor" href="#34-小结">#</a> 3.4. 小结</h2>
<p>上述的入门案例中中其实使用的是如下的简单模式：</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1555991074575.png"
                      alt="1555991074575"
                ></p>
<p>在上图的模型中，有以下概念：</p>
<ul>
<li>P：生产者，也就是要发送消息的程序</li>
<li>C：消费者：消息的接受者，会一直等待消息到来。</li>
<li>queue：消息队列，图中红色部分。类似一个邮箱，可以缓存消息；生产者向其中投递消息，消费者从其中取出消息。</li>
</ul>
<h1 id="4-amqp"><a class="markdownIt-Anchor" href="#4-amqp">#</a> 4. AMQP</h1>
<h2 id="41-相关概念介绍"><a class="markdownIt-Anchor" href="#41-相关概念介绍">#</a> 4.1. 相关概念介绍</h2>
<p>AMQP  一个提供统一消息服务的应用层标准高级消息队列协议，是应用层协议的一个开放标准，为面向消息的中间件设计。</p>
<p>AMQP 是一个二进制协议，拥有一些现代化特点：多信道、协商式，异步，安全，扩平台，中立，高效。</p>
<p>RabbitMQ 是 AMQP 协议的 Erlang 的实现。</p>
<table>
<thead>
<tr>
<th>概念</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>连接 Connection</td>
<td>一个网络连接，比如 TCP/IP 套接字连接。</td>
</tr>
<tr>
<td>会话 Session</td>
<td>端点之间的命名对话。在一个会话上下文中，保证 “恰好传递一次”。</td>
</tr>
<tr>
<td>信道 Channel</td>
<td>多路复用连接中的一条独立的双向数据流通道。为会话提供物理传输介质。</td>
</tr>
<tr>
<td>客户端 Client</td>
<td>AMQP 连接或者会话的发起者。AMQP 是非对称的，客户端生产和消费消息，服务器存储和路由这些消息。</td>
</tr>
<tr>
<td>服务节点 Broker</td>
<td>消息中间件的服务节点；一般情况下可以将一个 RabbitMQ Broker 看作一台 RabbitMQ 服务器。</td>
</tr>
<tr>
<td>端点</td>
<td>AMQP 对话的任意一方。一个 AMQP 连接包括两个端点（一个是客户端，一个是服务器）。</td>
</tr>
<tr>
<td>消费者 Consumer</td>
<td>一个从消息队列里请求消息的客户端程序。</td>
</tr>
<tr>
<td>生产者 Producer</td>
<td>一个向交换机发布消息的客户端应用程序。</td>
</tr>
</tbody>
</table>
<h2 id="42-rabbitmq运转流程"><a class="markdownIt-Anchor" href="#42-rabbitmq运转流程">#</a> 4.2. RabbitMQ 运转流程</h2>
<p>在入门案例中：</p>
<ul>
<li>生产者发送消息
<ol>
<li>生产者创建连接（Connection），开启一个信道（Channel），连接到 RabbitMQ Broker；</li>
<li>声明队列并设置属性；如是否排它，是否持久化，是否自动删除；</li>
<li>将路由键（空字符串）与队列绑定起来；</li>
<li>发送消息至 RabbitMQ Broker；</li>
<li>关闭信道；</li>
<li>关闭连接；</li>
</ol>
</li>
<li>消费者接收消息
<ol>
<li>消费者创建连接（Connection），开启一个信道（Channel），连接到 RabbitMQ Broker</li>
<li>向 Broker 请求消费相应队列中的消息，设置相应的回调函数；</li>
<li>等待 Broker 回应闭关投递响应队列中的消息，消费者接收消息；</li>
<li>确认（ack，自动确认）接收到的消息；</li>
<li>RabbitMQ 从队列中删除相应已经被确认的消息；</li>
<li>关闭信道；</li>
<li>关闭连接；</li>
</ol>
</li>
</ul>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1565105223969.png"
                      alt="1565105223969"
                ></p>
<h2 id="43-生产者流转过程说明"><a class="markdownIt-Anchor" href="#43-生产者流转过程说明">#</a> 4.3. 生产者流转过程说明</h2>
<ol>
<li>客户端与代理服务器 Broker 建立连接。会调用 newConnection () 方法，这个方法会进一步封装 Protocol Header 0-9-1 的报文头发送给 Broker ，以此通知 Broker 本次交互采用的是 AMQPO-9-1 协议，紧接着 Broker 返回 Connection.Start 来建立连接，在连接的过程中涉及 Connection.Start/.Start-OK 、Connection.Tune/.Tune-Ok ，Connection.Open/.Open-Ok 这 6 个命令的交互。</li>
<li>客户端调用 connection.createChannel 方法。此方法开启信道，其包装的 channel.open 命令发送给 Broker, 等待 channel.basicPublish 方法，对应的 AMQP 命令为 Basic.Publish, 这个命令包含了 content Header 和 content Body ()。content Header 包含了消息体的属性，例如：投递模式，优先级等，content Body 包含了消息体本身。</li>
<li>客户端发送完消息需要关闭资源时，涉及到 Channel.Close 和 Channl.Close-Ok 与 Connetion.Close 和 Connection.Close-Ok 的命令交互。</li>
</ol>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/%E7%94%9F%E4%BA%A7%E8%80%85%E6%B5%81%E8%BD%AC%E8%BF%87%E7%A8%8B%E5%9B%BE.bmp"
                      alt="生产者流转过程图"
                ></p>
<h2 id="44-消费者流转过程说明"><a class="markdownIt-Anchor" href="#44-消费者流转过程说明">#</a> 4.4. 消费者流转过程说明</h2>
<ol>
<li>消费者客户端与代理服务器 Broker 建立连接。会调用 newConnection () 方法，这个方法会进一步封装 Protocol Header 0-9-1 的报文头发送给 Broker ，以此通知 Broker 本次交互采用的是 AMQPO-9-1 协议，紧接着 Broker 返回 Connection.Start 来建立连接，在连接的过程中涉及 Connection.Start/.Start-OK 、Connection.Tune/.Tune-Ok ，Connection.Open/.Open-Ok 这 6 个命令的交互。</li>
<li>消费者客户端调用 connection.createChannel 方法。和生产者客户端一样，协议涉及 Channel . Open/Open-Ok 命令。</li>
<li>在真正消费之前，消费者客户端需要向 Broker 发送 Basic.Consume 命令 (即调用 channel.basicConsume 方法〉将 Channel 置为接收模式，之后 Broker 回执 Basic . Consume - Ok 以告诉消费者客户端准备好消费消息。</li>
<li>Broker 向消费者客户端推送 (Push) 消息，即 Basic.Deliver 命令，这个命令和 Basic.Publish 命令一样会携带 Content Header 和 Content Body。</li>
<li>消费者接收到消息并正确消费之后，向 Broker 发送确认，即 Basic.Ack 命令。</li>
<li>客户端发送完消息需要关闭资源时，涉及到 Channel.Close 和 Channl.Close-Ok 与 Connetion.Close 和 Connection.Close-Ok 的命令交互。</li>
</ol>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/%E6%B6%88%E8%B4%B9%E8%80%85%E6%B5%81%E8%BD%AC%E8%BF%87%E7%A8%8B%E5%9B%BE.bmp"
                      alt="消费者流转过程图"
                ></p>
<h1 id="5-rabbitmq工作模式"><a class="markdownIt-Anchor" href="#5-rabbitmq工作模式">#</a> 5. RabbitMQ 工作模式</h1>
<h2 id="41-work-queues工作队列模式"><a class="markdownIt-Anchor" href="#41-work-queues工作队列模式">#</a> 4.1. Work queues 工作队列模式</h2>
<h3 id="411-模式说明"><a class="markdownIt-Anchor" href="#411-模式说明">#</a> 4.1.1. 模式说明</h3>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556009144848.png"
                      alt="1556009144848"
                ></p>
<p><code>Work Queues</code>  与入门程序的 <code>简单模式</code> 相比，多了一个或一些消费端，多个消费端共同消费同一个队列中的消息。</p>
<p><strong>应用场景</strong>：对于 任务过重或任务较多情况使用工作队列可以提高任务处理的速度。</p>
<h3 id="412-代码"><a class="markdownIt-Anchor" href="#412-代码">#</a> 4.1.2. 代码</h3>
<p><code>Work Queues</code>  与入门程序的 <code>简单模式</code> 的代码是几乎一样的；可以完全复制，并复制多一个消费者进行多个消费者同时消费消息的测试。</p>
<h4 id="1生产者"><a class="markdownIt-Anchor" href="#1生产者">#</a> 1）生产者</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.work;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Channel;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Connection;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.ConnectionFactory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Producer</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">QUEUE_NAME</span> <span class="operator">=</span> <span class="string">&quot;work_queue&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建连接</span></span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(QUEUE_NAME, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">30</span>; i++) &#123;</span><br><span class="line">            <span class="comment">// 发送信息</span></span><br><span class="line">            <span class="type">String</span> <span class="variable">message</span> <span class="operator">=</span> <span class="string">&quot;你好；小兔子！work模式--&quot;</span> + i;</span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 参数1：交换机名称，如果没有指定则使用默认Default Exchage</span></span><br><span class="line"><span class="comment">             * 参数2：路由key,简单模式可以传递队列名称</span></span><br><span class="line"><span class="comment">             * 参数3：消息其它属性</span></span><br><span class="line"><span class="comment">             * 参数4：消息内容</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            channel.basicPublish(<span class="string">&quot;&quot;</span>, QUEUE_NAME, <span class="literal">null</span>, message.getBytes());</span><br><span class="line">            System.out.println(<span class="string">&quot;已发送消息：&quot;</span> + message);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        channel.close();</span><br><span class="line">        connection.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="2消费者1"><a class="markdownIt-Anchor" href="#2消费者1">#</a> 2）消费者 1</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.work;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer1</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.QUEUE_NAME, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//一次只能接收并处理一个消息</span></span><br><span class="line">        channel.basicQos(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="comment">//路由key</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                    <span class="comment">//交换机</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                    <span class="comment">//消息id</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                    <span class="comment">//收到的消息</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;消费者1-接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">                    Thread.sleep(<span class="number">1000</span>);</span><br><span class="line"></span><br><span class="line">                    <span class="comment">//确认消息</span></span><br><span class="line">                    channel.basicAck(envelope.getDeliveryTag(), <span class="literal">false</span>);</span><br><span class="line">                &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.QUEUE_NAME, <span class="literal">false</span>, consumer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<h4 id="3消费者2"><a class="markdownIt-Anchor" href="#3消费者2">#</a> 3）消费者 2</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.work;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer2</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.QUEUE_NAME, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//一次只能接收并处理一个消息</span></span><br><span class="line">        channel.basicQos(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="comment">//路由key</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                    <span class="comment">//交换机</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                    <span class="comment">//消息id</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                    <span class="comment">//收到的消息</span></span><br><span class="line">                    System.out.println(<span class="string">&quot;消费者2-接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">                    Thread.sleep(<span class="number">1000</span>);</span><br><span class="line"></span><br><span class="line">                    <span class="comment">//确认消息</span></span><br><span class="line">                    channel.basicAck(envelope.getDeliveryTag(), <span class="literal">false</span>);</span><br><span class="line">                &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.QUEUE_NAME, <span class="literal">false</span>, consumer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h3 id="413-测试"><a class="markdownIt-Anchor" href="#413-测试">#</a> 4.1.3. 测试</h3>
<p>启动两个消费者，然后再启动生产者发送消息；到 IDEA 的两个消费者对应的控制台查看是否竞争性的接收到消息。</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556014310859.png"
                      alt="1556014310859"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556014318106.png"
                      alt="1556014318106"
                ></p>
<h3 id="414-小结"><a class="markdownIt-Anchor" href="#414-小结">#</a> 4.1.4. 小结</h3>
<p>在一个队列中如果有多个消费者，那么消费者之间对于同一个消息的关系是<strong>竞争</strong>的关系。</p>
<h2 id="42-订阅模式类型"><a class="markdownIt-Anchor" href="#42-订阅模式类型">#</a> 4.2. 订阅模式类型</h2>
<p>订阅模式示例图：</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556014499573.png"
                      alt="1556014499573"
                ></p>
<p>前面 2 个案例中，只有 3 个角色：</p>
<ul>
<li>P：生产者，也就是要发送消息的程序</li>
<li>C：消费者：消息的接受者，会一直等待消息到来。</li>
<li>queue：消息队列，图中红色部分</li>
</ul>
<p>而在订阅模型中，多了一个 exchange 角色，而且过程略有变化：</p>
<ul>
<li>P：生产者，也就是要发送消息的程序，但是不再发送到队列中，而是发给 X（交换机）</li>
<li>C：消费者，消息的接受者，会一直等待消息到来。</li>
<li>Queue：消息队列，接收消息、缓存消息。</li>
<li>Exchange：交换机，图中的 X。一方面，接收生产者发送的消息。另一方面，知道如何处理消息，例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作，取决于 Exchange 的类型。Exchange 有常见以下 3 种类型：
<ul>
<li>Fanout：广播，将消息交给所有绑定到交换机的队列</li>
<li>Direct：定向，把消息交给符合指定 routing key 的队列</li>
<li>Topic：通配符，把消息交给符合 routing pattern（路由模式） 的队列</li>
</ul>
</li>
</ul>
<p><strong>Exchange（交换机）只负责转发消息，不具备存储消息的能力</strong>，因此如果没有任何队列与 Exchange 绑定，或者没有符合路由规则的队列，那么消息会丢失！</p>
<h2 id="43-publishsubscribe发布与订阅模式"><a class="markdownIt-Anchor" href="#43-publishsubscribe发布与订阅模式">#</a> 4.3. Publish/Subscribe 发布与订阅模式</h2>
<h3 id="431-模式说明"><a class="markdownIt-Anchor" href="#431-模式说明">#</a> 4.3.1. 模式说明</h3>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556010329032.png"
                      alt="1556010329032"
                ></p>
<p>发布订阅模式：<br>
1、每个消费者监听自己的队列。<br>
2、生产者将消息发给 broker，由交换机将消息转发到绑定此交换机的每个队列，每个绑定交换机的队列都将接收<br>
到消息</p>
<h3 id="432-代码"><a class="markdownIt-Anchor" href="#432-代码">#</a> 4.3.2. 代码</h3>
<h4 id="1生产者-2"><a class="markdownIt-Anchor" href="#1生产者-2">#</a> 1）生产者</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.ps;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.BuiltinExchangeType;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Channel;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Connection;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 发布与订阅使用的交换机类型为：fanout</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Producer</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//交换机名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">FANOUT_EXCHAGE</span> <span class="operator">=</span> <span class="string">&quot;fanout_exchange&quot;</span>;</span><br><span class="line">    <span class="comment">//队列名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">FANOUT_QUEUE_1</span> <span class="operator">=</span> <span class="string">&quot;fanout_queue_1&quot;</span>;</span><br><span class="line">    <span class="comment">//队列名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">FANOUT_QUEUE_2</span> <span class="operator">=</span> <span class="string">&quot;fanout_queue_2&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建连接</span></span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 声明交换机</span></span><br><span class="line"><span class="comment">         * 参数1：交换机名称</span></span><br><span class="line"><span class="comment">         * 参数2：交换机类型，fanout、topic、direct、headers</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.exchangeDeclare(FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(FANOUT_QUEUE_1, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line">        channel.queueDeclare(FANOUT_QUEUE_2, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//队列绑定交换机</span></span><br><span class="line">        channel.queueBind(FANOUT_QUEUE_1, FANOUT_EXCHAGE, <span class="string">&quot;&quot;</span>);</span><br><span class="line">        channel.queueBind(FANOUT_QUEUE_2, FANOUT_EXCHAGE, <span class="string">&quot;&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">10</span>; i++) &#123;</span><br><span class="line">            <span class="comment">// 发送信息</span></span><br><span class="line">            <span class="type">String</span> <span class="variable">message</span> <span class="operator">=</span> <span class="string">&quot;你好；小兔子！发布订阅模式--&quot;</span> + i;</span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 参数1：交换机名称，如果没有指定则使用默认Default Exchage</span></span><br><span class="line"><span class="comment">             * 参数2：路由key,简单模式可以传递队列名称</span></span><br><span class="line"><span class="comment">             * 参数3：消息其它属性</span></span><br><span class="line"><span class="comment">             * 参数4：消息内容</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            channel.basicPublish(FANOUT_EXCHAGE, <span class="string">&quot;&quot;</span>, <span class="literal">null</span>, message.getBytes());</span><br><span class="line">            System.out.println(<span class="string">&quot;已发送消息：&quot;</span> + message);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        channel.close();</span><br><span class="line">        connection.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<h4 id="2消费者1-2"><a class="markdownIt-Anchor" href="#2消费者1-2">#</a> 2）消费者 1</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.ps;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer1</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//声明交换机</span></span><br><span class="line">        channel.exchangeDeclare(Producer.FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.FANOUT_QUEUE_1, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//队列绑定交换机</span></span><br><span class="line">        channel.queueBind(Producer.FANOUT_QUEUE_1, Producer.FANOUT_EXCHAGE, <span class="string">&quot;&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="comment">//路由key</span></span><br><span class="line">                System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                <span class="comment">//交换机</span></span><br><span class="line">                System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                <span class="comment">//消息id</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                <span class="comment">//收到的消息</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消费者1-接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.FANOUT_QUEUE_1, <span class="literal">true</span>, consumer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="3消费者2-2"><a class="markdownIt-Anchor" href="#3消费者2-2">#</a> 3）消费者 2</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.ps;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer2</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//声明交换机</span></span><br><span class="line">        channel.exchangeDeclare(Producer.FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.FANOUT_QUEUE_2, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//队列绑定交换机</span></span><br><span class="line">        channel.queueBind(Producer.FANOUT_QUEUE_2, Producer.FANOUT_EXCHAGE, <span class="string">&quot;&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="comment">//路由key</span></span><br><span class="line">                System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                <span class="comment">//交换机</span></span><br><span class="line">                System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                <span class="comment">//消息id</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                <span class="comment">//收到的消息</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消费者2-接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.FANOUT_QUEUE_2, <span class="literal">true</span>, consumer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<h3 id="433-测试"><a class="markdownIt-Anchor" href="#433-测试">#</a> 4.3.3. 测试</h3>
<p>启动所有消费者，然后使用生产者发送消息；在每个消费者对应的控制台可以查看到生产者发送的所有消息；到达<strong>广播</strong>的效果。</p>
<p>在执行完测试代码后，其实到 RabbitMQ 的管理后台找到 <code>Exchanges</code>  选项卡，点击  <code>fanout_exchange</code>  的交换机，可以查看到如下的绑定：</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556015006220.png"
                      alt="1556015006220"
                ></p>
<h3 id="434-小结"><a class="markdownIt-Anchor" href="#434-小结">#</a> 4.3.4. 小结</h3>
<p>交换机需要与队列进行绑定，绑定之后；一个消息可以被多个消费者都收到。</p>
<p><strong>发布订阅模式与工作队列模式的区别</strong></p>
<p>1、工作队列模式不用定义交换机，而发布 / 订阅模式需要定义交换机。</p>
<p>2、发布 / 订阅模式的生产方是面向交换机发送消息，工作队列模式的生产方是面向队列发送消息 (底层使用默认交换机)。</p>
<p>3、发布 / 订阅模式需要设置队列和交换机的绑定，工作队列模式不需要设置，实际上工作队列模式会将队列绑 定到默认的交换机 。</p>
<h2 id="44-routing路由模式"><a class="markdownIt-Anchor" href="#44-routing路由模式">#</a> 4.4. Routing 路由模式</h2>
<h3 id="441-模式说明"><a class="markdownIt-Anchor" href="#441-模式说明">#</a> 4.4.1. 模式说明</h3>
<p>路由模式特点：</p>
<ul>
<li>队列与交换机的绑定，不能是任意绑定了，而是要指定一个 <code>RoutingKey</code> （路由 key）</li>
<li>消息的发送方在 向 Exchange 发送消息时，也必须指定消息的  <code>RoutingKey</code> 。</li>
<li>Exchange 不再把消息交给每一个绑定的队列，而是根据消息的 <code>Routing Key</code>  进行判断，只有队列的 <code>Routingkey</code>  与消息的  <code>Routing key</code>  完全一致，才会接收到消息</li>
</ul>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556029284397.png"
                      alt="1556029284397"
                ></p>
<p>图解：</p>
<ul>
<li>P：生产者，向 Exchange 发送消息，发送消息时，会指定一个 routing key。</li>
<li>X：Exchange（交换机），接收生产者的消息，然后把消息递交给 与 routing key 完全匹配的队列</li>
<li>C1：消费者，其所在队列指定了需要 routing key 为 error 的消息</li>
<li>C2：消费者，其所在队列指定了需要 routing key 为 info、error、warning 的消息</li>
</ul>
<h3 id="442-代码"><a class="markdownIt-Anchor" href="#442-代码">#</a> 4.4.2. 代码</h3>
<p>在编码上与  <code>Publish/Subscribe发布与订阅模式</code>  的区别是交换机的类型为：Direct，还有队列绑定交换机的时候需要指定 routing key。</p>
<h4 id="1生产者-3"><a class="markdownIt-Anchor" href="#1生产者-3">#</a> 1）生产者</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.routing;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.BuiltinExchangeType;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Channel;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Connection;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 路由模式的交换机类型为：direct</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Producer</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//交换机名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">DIRECT_EXCHAGE</span> <span class="operator">=</span> <span class="string">&quot;direct_exchange&quot;</span>;</span><br><span class="line">    <span class="comment">//队列名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">DIRECT_QUEUE_INSERT</span> <span class="operator">=</span> <span class="string">&quot;direct_queue_insert&quot;</span>;</span><br><span class="line">    <span class="comment">//队列名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">DIRECT_QUEUE_UPDATE</span> <span class="operator">=</span> <span class="string">&quot;direct_queue_update&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建连接</span></span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 声明交换机</span></span><br><span class="line"><span class="comment">         * 参数1：交换机名称</span></span><br><span class="line"><span class="comment">         * 参数2：交换机类型，fanout、topic、direct、headers</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.exchangeDeclare(DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(DIRECT_QUEUE_INSERT, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line">        channel.queueDeclare(DIRECT_QUEUE_UPDATE, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//队列绑定交换机</span></span><br><span class="line">        channel.queueBind(DIRECT_QUEUE_INSERT, DIRECT_EXCHAGE, <span class="string">&quot;insert&quot;</span>);</span><br><span class="line">        channel.queueBind(DIRECT_QUEUE_UPDATE, DIRECT_EXCHAGE, <span class="string">&quot;update&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 发送信息</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">message</span> <span class="operator">=</span> <span class="string">&quot;新增了商品。路由模式；routing key 为 insert &quot;</span> ;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：交换机名称，如果没有指定则使用默认Default Exchage</span></span><br><span class="line"><span class="comment">         * 参数2：路由key,简单模式可以传递队列名称</span></span><br><span class="line"><span class="comment">         * 参数3：消息其它属性</span></span><br><span class="line"><span class="comment">         * 参数4：消息内容</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicPublish(DIRECT_EXCHAGE, <span class="string">&quot;insert&quot;</span>, <span class="literal">null</span>, message.getBytes());</span><br><span class="line">        System.out.println(<span class="string">&quot;已发送消息：&quot;</span> + message);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 发送信息</span></span><br><span class="line">        message = <span class="string">&quot;修改了商品。路由模式；routing key 为 update&quot;</span> ;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：交换机名称，如果没有指定则使用默认Default Exchage</span></span><br><span class="line"><span class="comment">         * 参数2：路由key,简单模式可以传递队列名称</span></span><br><span class="line"><span class="comment">         * 参数3：消息其它属性</span></span><br><span class="line"><span class="comment">         * 参数4：消息内容</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicPublish(DIRECT_EXCHAGE, <span class="string">&quot;update&quot;</span>, <span class="literal">null</span>, message.getBytes());</span><br><span class="line">        System.out.println(<span class="string">&quot;已发送消息：&quot;</span> + message);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        channel.close();</span><br><span class="line">        connection.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="2消费者1-3"><a class="markdownIt-Anchor" href="#2消费者1-3">#</a> 2）消费者 1</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.routing;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer1</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//声明交换机</span></span><br><span class="line">        channel.exchangeDeclare(Producer.DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.DIRECT_QUEUE_INSERT, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//队列绑定交换机</span></span><br><span class="line">        channel.queueBind(Producer.DIRECT_QUEUE_INSERT, Producer.DIRECT_EXCHAGE, <span class="string">&quot;insert&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="comment">//路由key</span></span><br><span class="line">                System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                <span class="comment">//交换机</span></span><br><span class="line">                System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                <span class="comment">//消息id</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                <span class="comment">//收到的消息</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消费者1-接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.DIRECT_QUEUE_INSERT, <span class="literal">true</span>, consumer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="3消费者2-3"><a class="markdownIt-Anchor" href="#3消费者2-3">#</a> 3）消费者 2</h4>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.routing;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer2</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//声明交换机</span></span><br><span class="line">        channel.exchangeDeclare(Producer.DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.DIRECT_QUEUE_UPDATE, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//队列绑定交换机</span></span><br><span class="line">        channel.queueBind(Producer.DIRECT_QUEUE_UPDATE, Producer.DIRECT_EXCHAGE, <span class="string">&quot;update&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="comment">//路由key</span></span><br><span class="line">                System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                <span class="comment">//交换机</span></span><br><span class="line">                System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                <span class="comment">//消息id</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                <span class="comment">//收到的消息</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消费者2-接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.DIRECT_QUEUE_UPDATE, <span class="literal">true</span>, consumer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h3 id="443-测试"><a class="markdownIt-Anchor" href="#443-测试">#</a> 4.4.3. 测试</h3>
<p>启动所有消费者，然后使用生产者发送消息；在消费者对应的控制台可以查看到生产者发送对应 routing key 对应队列的消息；到达<strong>按照需要接收</strong>的效果。</p>
<p>在执行完测试代码后，其实到 RabbitMQ 的管理后台找到 <code>Exchanges</code>  选项卡，点击  <code>direct_exchange</code>  的交换机，可以查看到如下的绑定：</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556031175744.png"
                      alt="1556031175744"
                ></p>
<h3 id="444-小结"><a class="markdownIt-Anchor" href="#444-小结">#</a> 4.4.4. 小结</h3>
<p>Routing 模式要求队列在绑定交换机时要指定 routing key，消息会转发到符合 routing key 的队列。</p>
<h2 id="45-topics通配符模式"><a class="markdownIt-Anchor" href="#45-topics通配符模式">#</a> 4.5. Topics 通配符模式</h2>
<h3 id="451-模式说明"><a class="markdownIt-Anchor" href="#451-模式说明">#</a> 4.5.1. 模式说明</h3>
<p><code>Topic</code>  类型与 <code>Direct</code>  相比，都是可以根据 <code>RoutingKey</code>  把消息路由到不同的队列。只不过 <code>Topic</code>  类型 <code>Exchange</code>  可以让队列在绑定 <code>Routing key</code>  的时候<strong>使用通配符</strong>！</p>
<p><code>Routingkey</code>  一般都是有一个或多个单词组成，多个单词之间以”.” 分割，例如：  <code>item.insert</code></p>
<p>通配符规则：</p>
<p><code>#</code> ：匹配一个或多个词</p>
<p><code>*</code> ：匹配不多不少恰好 1 个词</p>
<p>举例：</p>
<p><code>item.#</code> ：能够匹配 <code>item.insert.abc</code>  或者  <code>item.insert</code></p>
<p><code>item.*</code> ：只能匹配 <code>item.insert</code></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556031362048.png"
                      alt="1556031362048"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556031519931.png"
                      alt="1556031519931"
                ></p>
<p>图解：</p>
<ul>
<li>红色 Queue：绑定的是 <code>usa.#</code>  ，因此凡是以  <code>usa.</code>  开头的 <code>routing key</code>  都会被匹配到</li>
<li>黄色 Queue：绑定的是 <code>#.news</code>  ，因此凡是以  <code>.news</code>  结尾的  <code>routing key</code>  都会被匹配</li>
</ul>
<h3 id="452-代码"><a class="markdownIt-Anchor" href="#452-代码">#</a> 4.5.2. 代码</h3>
<h4 id="1生产者-4"><a class="markdownIt-Anchor" href="#1生产者-4">#</a> 1）生产者</h4>
<p>使用 topic 类型的 Exchange，发送消息的 routing key 有 3 种：  <code>item.insert</code> 、 <code>item.update</code> 、 <code>item.delete</code> ：</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.topic;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.BuiltinExchangeType;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Channel;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.Connection;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 通配符Topic的交换机类型为：topic</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Producer</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//交换机名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">TOPIC_EXCHAGE</span> <span class="operator">=</span> <span class="string">&quot;topic_exchange&quot;</span>;</span><br><span class="line">    <span class="comment">//队列名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">TOPIC_QUEUE_1</span> <span class="operator">=</span> <span class="string">&quot;topic_queue_1&quot;</span>;</span><br><span class="line">    <span class="comment">//队列名称</span></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">TOPIC_QUEUE_2</span> <span class="operator">=</span> <span class="string">&quot;topic_queue_2&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建连接</span></span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 声明交换机</span></span><br><span class="line"><span class="comment">         * 参数1：交换机名称</span></span><br><span class="line"><span class="comment">         * 参数2：交换机类型，fanout、topic、topic、headers</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.exchangeDeclare(TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 发送信息</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">message</span> <span class="operator">=</span> <span class="string">&quot;新增了商品。Topic模式；routing key 为 item.insert &quot;</span> ;</span><br><span class="line">        channel.basicPublish(TOPIC_EXCHAGE, <span class="string">&quot;item.insert&quot;</span>, <span class="literal">null</span>, message.getBytes());</span><br><span class="line">        System.out.println(<span class="string">&quot;已发送消息：&quot;</span> + message);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 发送信息</span></span><br><span class="line">        message = <span class="string">&quot;修改了商品。Topic模式；routing key 为 item.update&quot;</span> ;</span><br><span class="line">        channel.basicPublish(TOPIC_EXCHAGE, <span class="string">&quot;item.update&quot;</span>, <span class="literal">null</span>, message.getBytes());</span><br><span class="line">        System.out.println(<span class="string">&quot;已发送消息：&quot;</span> + message);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 发送信息</span></span><br><span class="line">        message = <span class="string">&quot;删除了商品。Topic模式；routing key 为 item.delete&quot;</span> ;</span><br><span class="line">        channel.basicPublish(TOPIC_EXCHAGE, <span class="string">&quot;item.delete&quot;</span>, <span class="literal">null</span>, message.getBytes());</span><br><span class="line">        System.out.println(<span class="string">&quot;已发送消息：&quot;</span> + message);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        channel.close();</span><br><span class="line">        connection.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="2消费者1-4"><a class="markdownIt-Anchor" href="#2消费者1-4">#</a> 2）消费者 1</h4>
<p>接收两种类型的消息：更新商品和删除商品</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.topic;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer1</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//声明交换机</span></span><br><span class="line">        channel.exchangeDeclare(Producer.TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.TOPIC_QUEUE_1, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//队列绑定交换机</span></span><br><span class="line">        channel.queueBind(Producer.TOPIC_QUEUE_1, Producer.TOPIC_EXCHAGE, <span class="string">&quot;item.update&quot;</span>);</span><br><span class="line">        channel.queueBind(Producer.TOPIC_QUEUE_1, Producer.TOPIC_EXCHAGE, <span class="string">&quot;item.delete&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="comment">//路由key</span></span><br><span class="line">                System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                <span class="comment">//交换机</span></span><br><span class="line">                System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                <span class="comment">//消息id</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                <span class="comment">//收到的消息</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消费者1-接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.TOPIC_QUEUE_1, <span class="literal">true</span>, consumer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="3消费者2-4"><a class="markdownIt-Anchor" href="#3消费者2-4">#</a> 3）消费者 2</h4>
<p>接收所有类型的消息：新增商品，更新商品和删除商品。</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.topic;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.util.ConnectionUtil;</span><br><span class="line"><span class="keyword">import</span> com.rabbitmq.client.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Consumer2</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> ConnectionUtil.getConnection();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建频道</span></span><br><span class="line">        <span class="type">Channel</span> <span class="variable">channel</span> <span class="operator">=</span> connection.createChannel();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//声明交换机</span></span><br><span class="line">        channel.exchangeDeclare(Producer.TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 声明（创建）队列</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否定义持久化队列</span></span><br><span class="line"><span class="comment">         * 参数3：是否独占本次连接</span></span><br><span class="line"><span class="comment">         * 参数4：是否在不使用的时候自动删除队列</span></span><br><span class="line"><span class="comment">         * 参数5：队列其它参数</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.queueDeclare(Producer.TOPIC_QUEUE_2, <span class="literal">true</span>, <span class="literal">false</span>, <span class="literal">false</span>, <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//队列绑定交换机</span></span><br><span class="line">        channel.queueBind(Producer.TOPIC_QUEUE_2, Producer.TOPIC_EXCHAGE, <span class="string">&quot;item.*&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//创建消费者；并设置消息处理</span></span><br><span class="line">        <span class="type">DefaultConsumer</span> <span class="variable">consumer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DefaultConsumer</span>(channel)&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * consumerTag 消息者标签，在channel.basicConsume时候可以指定</span></span><br><span class="line"><span class="comment">             * envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志(收到消息失败后是否需要重新发送)</span></span><br><span class="line"><span class="comment">             * properties 属性信息</span></span><br><span class="line"><span class="comment">             * body 消息</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleDelivery</span><span class="params">(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, <span class="type">byte</span>[] body)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">                <span class="comment">//路由key</span></span><br><span class="line">                System.out.println(<span class="string">&quot;路由key为：&quot;</span> + envelope.getRoutingKey());</span><br><span class="line">                <span class="comment">//交换机</span></span><br><span class="line">                System.out.println(<span class="string">&quot;交换机为：&quot;</span> + envelope.getExchange());</span><br><span class="line">                <span class="comment">//消息id</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消息id为：&quot;</span> + envelope.getDeliveryTag());</span><br><span class="line">                <span class="comment">//收到的消息</span></span><br><span class="line">                System.out.println(<span class="string">&quot;消费者2-接收到的消息为：&quot;</span> + <span class="keyword">new</span> <span class="title class_">String</span>(body, <span class="string">&quot;utf-8&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//监听消息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：队列名称</span></span><br><span class="line"><span class="comment">         * 参数2：是否自动确认，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置为false则需要手动确认</span></span><br><span class="line"><span class="comment">         * 参数3：消息接收到后回调</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        channel.basicConsume(Producer.TOPIC_QUEUE_2, <span class="literal">true</span>, consumer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h3 id="453-测试"><a class="markdownIt-Anchor" href="#453-测试">#</a> 4.5.3. 测试</h3>
<p>启动所有消费者，然后使用生产者发送消息；在消费者对应的控制台可以查看到生产者发送对应 routing key 对应队列的消息；到达<strong>按照需要接收</strong>的效果；并且这些 routing key 可以使用通配符。</p>
<p>在执行完测试代码后，其实到 RabbitMQ 的管理后台找到 <code>Exchanges</code>  选项卡，点击  <code>topic_exchange</code>  的交换机，可以查看到如下的绑定：</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556032433333.png"
                      alt="1556032433333"
                ></p>
<h3 id="454-小结"><a class="markdownIt-Anchor" href="#454-小结">#</a> 4.5.4. 小结</h3>
<p>Topic 主题模式可以实现  <code>Publish/Subscribe发布与订阅模式</code>  和  <code> Routing路由模式</code>  的功能；只是 Topic 在配置 routing key 的时候可以使用通配符，显得更加灵活。</p>
<h2 id="46-模式总结"><a class="markdownIt-Anchor" href="#46-模式总结">#</a> 4.6. 模式总结</h2>
<p>RabbitMQ 工作模式：<br>
<strong>1、简单模式 HelloWorld</strong><br>
 一个生产者、一个消费者，不需要设置交换机（使用默认的交换机）</p>
<p><strong>2、工作队列模式 Work Queue</strong><br>
 一个生产者、多个消费者（竞争关系），不需要设置交换机（使用默认的交换机）</p>
<p><strong>3、发布订阅模式 Publish/subscribe</strong><br>
 需要设置类型为 fanout 的交换机，并且交换机和队列进行绑定，当发送消息到交换机后，交换机会将消息发送到绑定的队列</p>
<p><strong>4、路由模式 Routing</strong><br>
 需要设置类型为 direct 的交换机，交换机和队列进行绑定，并且指定 routing key，当发送消息到交换机后，交换机会根据 routing key 将消息发送到对应的队列</p>
<p><strong>5、通配符模式 Topic</strong><br>
 需要设置类型为 topic 的交换机，交换机和队列进行绑定，并且指定通配符方式的 routing key，当发送消息到交换机后，交换机会根据 routing key 将消息发送到对应的队列</p>
<h1 id="5-spring-整合rabbitmq"><a class="markdownIt-Anchor" href="#5-spring-整合rabbitmq">#</a> 5. Spring 整合 RabbitMQ</h1>
<h2 id="51-搭建生产者工程"><a class="markdownIt-Anchor" href="#51-搭建生产者工程">#</a> 5.1. 搭建生产者工程</h2>
<h3 id="511-创建工程"><a class="markdownIt-Anchor" href="#511-创建工程">#</a> 5.1.1. 创建工程</h3>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1565149342994.png"
                      alt="1565149342994"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1565144326498.png"
                      alt="1565144326498"
                ></p>
<h3 id="512-添加依赖"><a class="markdownIt-Anchor" href="#512-添加依赖">#</a> 5.1.2. 添加依赖</h3>
<p>修改 pom.xml 文件内容为如下：</p>
<div class="highlight-container" data-rel="Xml"><figure class="iseeu highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.itheima<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-rabbitmq-producer<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.0-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-context<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.1.7.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.amqp<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-rabbit<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.8.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>junit<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>junit<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>4.12<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-test<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.1.7.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br></pre></td></tr></table></figure></div>
<h3 id="513-配置整合"><a class="markdownIt-Anchor" href="#513-配置整合">#</a> 5.1.3. 配置整合</h3>
<ol>
<li>创建 <code>spring-rabbitmq-producer\src\main\resources\properties\rabbitmq.properties</code>  连接参数等配置文件；</li>
</ol>
<div class="highlight-container" data-rel="Properties"><figure class="iseeu highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">rabbitmq.host</span>=<span class="string">192.168.12.135</span></span><br><span class="line"><span class="attr">rabbitmq.port</span>=<span class="string">5672</span></span><br><span class="line"><span class="attr">rabbitmq.username</span>=<span class="string">heima</span></span><br><span class="line"><span class="attr">rabbitmq.password</span>=<span class="string">heima</span></span><br><span class="line"><span class="attr">rabbitmq.virtual-host</span>=<span class="string">/itcast</span></span><br></pre></td></tr></table></figure></div>
<ol start="2">
<li>创建  <code>spring-rabbitmq-producer\src\main\resources\spring\spring-rabbitmq.xml</code>  整合配置文件；</li>
</ol>
<div class="highlight-container" data-rel="Xml"><figure class="iseeu highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">&quot;http://www.springframework.org/schema/context&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:rabbit</span>=<span class="string">&quot;http://www.springframework.org/schema/rabbit&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="string"><span class="tag">       http://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">       http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="string"><span class="tag">       https://www.springframework.org/schema/context/spring-context.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">       http://www.springframework.org/schema/rabbit</span></span></span><br><span class="line"><span class="string"><span class="tag">       http://www.springframework.org/schema/rabbit/spring-rabbit.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--加载配置文件--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:property-placeholder</span> <span class="attr">location</span>=<span class="string">&quot;classpath:properties/rabbitmq.properties&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- 定义rabbitmq connectionFactory --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:connection-factory</span> <span class="attr">id</span>=<span class="string">&quot;connectionFactory&quot;</span> <span class="attr">host</span>=<span class="string">&quot;$&#123;rabbitmq.host&#125;&quot;</span></span></span><br><span class="line"><span class="tag">                               <span class="attr">port</span>=<span class="string">&quot;$&#123;rabbitmq.port&#125;&quot;</span></span></span><br><span class="line"><span class="tag">                               <span class="attr">username</span>=<span class="string">&quot;$&#123;rabbitmq.username&#125;&quot;</span></span></span><br><span class="line"><span class="tag">                               <span class="attr">password</span>=<span class="string">&quot;$&#123;rabbitmq.password&#125;&quot;</span></span></span><br><span class="line"><span class="tag">                               <span class="attr">virtual-host</span>=<span class="string">&quot;$&#123;rabbitmq.virtual-host&#125;&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--定义管理交换机、队列--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:admin</span> <span class="attr">connection-factory</span>=<span class="string">&quot;connectionFactory&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--定义持久化队列，不存在则自动创建；不绑定到交换机则绑定到默认交换机</span></span><br><span class="line"><span class="comment">    默认交换机类型为direct，名字为：&quot;&quot;，路由键为队列的名称</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:queue</span> <span class="attr">id</span>=<span class="string">&quot;spring_queue&quot;</span> <span class="attr">name</span>=<span class="string">&quot;spring_queue&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~广播；所有队列都能收到消息~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--定义广播交换机中的持久化队列，不存在则自动创建--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:queue</span> <span class="attr">id</span>=<span class="string">&quot;spring_fanout_queue_1&quot;</span> <span class="attr">name</span>=<span class="string">&quot;spring_fanout_queue_1&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--定义广播交换机中的持久化队列，不存在则自动创建--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:queue</span> <span class="attr">id</span>=<span class="string">&quot;spring_fanout_queue_2&quot;</span> <span class="attr">name</span>=<span class="string">&quot;spring_fanout_queue_2&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--定义广播类型交换机；并绑定上述两个队列--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:fanout-exchange</span> <span class="attr">id</span>=<span class="string">&quot;spring_fanout_exchange&quot;</span> <span class="attr">name</span>=<span class="string">&quot;spring_fanout_exchange&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">rabbit:bindings</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">rabbit:binding</span> <span class="attr">queue</span>=<span class="string">&quot;spring_fanout_queue_1&quot;</span>/&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">rabbit:binding</span> <span class="attr">queue</span>=<span class="string">&quot;spring_fanout_queue_2&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">rabbit:bindings</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">rabbit:fanout-exchange</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~通配符；*匹配一个单词，#匹配多个单词 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--定义广播交换机中的持久化队列，不存在则自动创建--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:queue</span> <span class="attr">id</span>=<span class="string">&quot;spring_topic_queue_star&quot;</span> <span class="attr">name</span>=<span class="string">&quot;spring_topic_queue_star&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--定义广播交换机中的持久化队列，不存在则自动创建--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:queue</span> <span class="attr">id</span>=<span class="string">&quot;spring_topic_queue_well&quot;</span> <span class="attr">name</span>=<span class="string">&quot;spring_topic_queue_well&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--定义广播交换机中的持久化队列，不存在则自动创建--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:queue</span> <span class="attr">id</span>=<span class="string">&quot;spring_topic_queue_well2&quot;</span> <span class="attr">name</span>=<span class="string">&quot;spring_topic_queue_well2&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:topic-exchange</span> <span class="attr">id</span>=<span class="string">&quot;spring_topic_exchange&quot;</span> <span class="attr">name</span>=<span class="string">&quot;spring_topic_exchange&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">rabbit:bindings</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">rabbit:binding</span> <span class="attr">pattern</span>=<span class="string">&quot;heima.*&quot;</span> <span class="attr">queue</span>=<span class="string">&quot;spring_topic_queue_star&quot;</span>/&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">rabbit:binding</span> <span class="attr">pattern</span>=<span class="string">&quot;heima.#&quot;</span> <span class="attr">queue</span>=<span class="string">&quot;spring_topic_queue_well&quot;</span>/&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">rabbit:binding</span> <span class="attr">pattern</span>=<span class="string">&quot;itcast.#&quot;</span> <span class="attr">queue</span>=<span class="string">&quot;spring_topic_queue_well2&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">rabbit:bindings</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">rabbit:topic-exchange</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--定义rabbitTemplate对象操作可以在代码中方便发送消息--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:template</span> <span class="attr">id</span>=<span class="string">&quot;rabbitTemplate&quot;</span> <span class="attr">connection-factory</span>=<span class="string">&quot;connectionFactory&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure></div>
<h3 id="514-发送消息"><a class="markdownIt-Anchor" href="#514-发送消息">#</a> 5.1.4. 发送消息</h3>
<p>创建测试文件  <code>spring-rabbitmq-producer\src\test\java\com\itheima\rabbitmq\ProducerTest.java</code></p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RunWith(SpringJUnit4ClassRunner.class)</span></span><br><span class="line"><span class="meta">@ContextConfiguration(locations = &quot;classpath:spring/spring-rabbitmq.xml&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ProducerTest</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> RabbitTemplate rabbitTemplate;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 只发队列消息</span></span><br><span class="line"><span class="comment">     * 默认交换机类型为 direct</span></span><br><span class="line"><span class="comment">     * 交换机的名称为空，路由键为队列的名称</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">queueTest</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="comment">//路由键与队列同名</span></span><br><span class="line">        rabbitTemplate.convertAndSend(<span class="string">&quot;spring_queue&quot;</span>, <span class="string">&quot;只发队列spring_queue的消息。&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 发送广播</span></span><br><span class="line"><span class="comment">     * 交换机类型为 fanout</span></span><br><span class="line"><span class="comment">     * 绑定到该交换机的所有队列都能够收到消息</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fanoutTest</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：交换机名称</span></span><br><span class="line"><span class="comment">         * 参数2：路由键名（广播设置为空）</span></span><br><span class="line"><span class="comment">         * 参数3：发送的消息内容</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        rabbitTemplate.convertAndSend(<span class="string">&quot;spring_fanout_exchange&quot;</span>, <span class="string">&quot;&quot;</span>, <span class="string">&quot;发送到spring_fanout_exchange交换机的广播消息&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 通配符</span></span><br><span class="line"><span class="comment">     * 交换机类型为 topic</span></span><br><span class="line"><span class="comment">     * 匹配路由键的通配符，*表示一个单词，#表示多个单词</span></span><br><span class="line"><span class="comment">     * 绑定到该交换机的匹配队列能够收到对应消息</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">topicTest</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 参数1：交换机名称</span></span><br><span class="line"><span class="comment">         * 参数2：路由键名</span></span><br><span class="line"><span class="comment">         * 参数3：发送的消息内容</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        rabbitTemplate.convertAndSend(<span class="string">&quot;spring_topic_exchange&quot;</span>, <span class="string">&quot;heima.bj&quot;</span>, <span class="string">&quot;发送到spring_topic_exchange交换机heima.bj的消息&quot;</span>);</span><br><span class="line">        rabbitTemplate.convertAndSend(<span class="string">&quot;spring_topic_exchange&quot;</span>, <span class="string">&quot;heima.bj.1&quot;</span>, <span class="string">&quot;发送到spring_topic_exchange交换机heima.bj.1的消息&quot;</span>);</span><br><span class="line">        rabbitTemplate.convertAndSend(<span class="string">&quot;spring_topic_exchange&quot;</span>, <span class="string">&quot;heima.bj.2&quot;</span>, <span class="string">&quot;发送到spring_topic_exchange交换机heima.bj.2的消息&quot;</span>);</span><br><span class="line">        rabbitTemplate.convertAndSend(<span class="string">&quot;spring_topic_exchange&quot;</span>, <span class="string">&quot;itcast.cn&quot;</span>, <span class="string">&quot;发送到spring_topic_exchange交换机itcast.cn的消息&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h2 id="52-搭建消费者工程"><a class="markdownIt-Anchor" href="#52-搭建消费者工程">#</a> 5.2. 搭建消费者工程</h2>
<h3 id="521-创建工程"><a class="markdownIt-Anchor" href="#521-创建工程">#</a> 5.2.1. 创建工程</h3>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1565149374831.png"
                      alt="1565149374831"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1565144775216.png"
                      alt="1565144775216"
                ></p>
<h3 id="522-添加依赖"><a class="markdownIt-Anchor" href="#522-添加依赖">#</a> 5.2.2. 添加依赖</h3>
<p>修改 pom.xml 文件内容为如下：</p>
<div class="highlight-container" data-rel="Xml"><figure class="iseeu highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.itheima<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-rabbitmq-consumer<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.0-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-context<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.1.7.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.amqp<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-rabbit<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.8.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br></pre></td></tr></table></figure></div>
<h3 id="523-配置整合"><a class="markdownIt-Anchor" href="#523-配置整合">#</a> 5.2.3. 配置整合</h3>
<ol>
<li>创建 <code>spring-rabbitmq-consumer\src\main\resources\properties\rabbitmq.properties</code>  连接参数等配置文件；</li>
</ol>
<div class="highlight-container" data-rel="Properties"><figure class="iseeu highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">rabbitmq.host</span>=<span class="string">192.168.12.135</span></span><br><span class="line"><span class="attr">rabbitmq.port</span>=<span class="string">5672</span></span><br><span class="line"><span class="attr">rabbitmq.username</span>=<span class="string">heima</span></span><br><span class="line"><span class="attr">rabbitmq.password</span>=<span class="string">heima</span></span><br><span class="line"><span class="attr">rabbitmq.virtual-host</span>=<span class="string">/itcast</span></span><br></pre></td></tr></table></figure></div>
<ol start="2">
<li>创建  <code>spring-rabbitmq-consumer\src\main\resources\spring\spring-rabbitmq.xml</code>  整合配置文件；</li>
</ol>
<div class="highlight-container" data-rel="Xml"><figure class="iseeu highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">&quot;http://www.springframework.org/schema/context&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:rabbit</span>=<span class="string">&quot;http://www.springframework.org/schema/rabbit&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="string"><span class="tag">       http://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">       http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="string"><span class="tag">       https://www.springframework.org/schema/context/spring-context.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">       http://www.springframework.org/schema/rabbit</span></span></span><br><span class="line"><span class="string"><span class="tag">       http://www.springframework.org/schema/rabbit/spring-rabbit.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--加载配置文件--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:property-placeholder</span> <span class="attr">location</span>=<span class="string">&quot;classpath:properties/rabbitmq.properties&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- 定义rabbitmq connectionFactory --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:connection-factory</span> <span class="attr">id</span>=<span class="string">&quot;connectionFactory&quot;</span> <span class="attr">host</span>=<span class="string">&quot;$&#123;rabbitmq.host&#125;&quot;</span></span></span><br><span class="line"><span class="tag">                               <span class="attr">port</span>=<span class="string">&quot;$&#123;rabbitmq.port&#125;&quot;</span></span></span><br><span class="line"><span class="tag">                               <span class="attr">username</span>=<span class="string">&quot;$&#123;rabbitmq.username&#125;&quot;</span></span></span><br><span class="line"><span class="tag">                               <span class="attr">password</span>=<span class="string">&quot;$&#123;rabbitmq.password&#125;&quot;</span></span></span><br><span class="line"><span class="tag">                               <span class="attr">virtual-host</span>=<span class="string">&quot;$&#123;rabbitmq.virtual-host&#125;&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;springQueueListener&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.rabbitmq.listener.SpringQueueListener&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;fanoutListener1&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.rabbitmq.listener.FanoutListener1&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;fanoutListener2&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.rabbitmq.listener.FanoutListener2&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;topicListenerStar&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.rabbitmq.listener.TopicListenerStar&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;topicListenerWell&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.rabbitmq.listener.TopicListenerWell&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;topicListenerWell2&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.itheima.rabbitmq.listener.TopicListenerWell2&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">rabbit:listener-container</span> <span class="attr">connection-factory</span>=<span class="string">&quot;connectionFactory&quot;</span> <span class="attr">auto-declare</span>=<span class="string">&quot;true&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">rabbit:listener</span> <span class="attr">ref</span>=<span class="string">&quot;springQueueListener&quot;</span> <span class="attr">queue-names</span>=<span class="string">&quot;spring_queue&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">rabbit:listener</span> <span class="attr">ref</span>=<span class="string">&quot;fanoutListener1&quot;</span> <span class="attr">queue-names</span>=<span class="string">&quot;spring_fanout_queue_1&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">rabbit:listener</span> <span class="attr">ref</span>=<span class="string">&quot;fanoutListener2&quot;</span> <span class="attr">queue-names</span>=<span class="string">&quot;spring_fanout_queue_2&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">rabbit:listener</span> <span class="attr">ref</span>=<span class="string">&quot;topicListenerStar&quot;</span> <span class="attr">queue-names</span>=<span class="string">&quot;spring_topic_queue_star&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">rabbit:listener</span> <span class="attr">ref</span>=<span class="string">&quot;topicListenerWell&quot;</span> <span class="attr">queue-names</span>=<span class="string">&quot;spring_topic_queue_well&quot;</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">rabbit:listener</span> <span class="attr">ref</span>=<span class="string">&quot;topicListenerWell2&quot;</span> <span class="attr">queue-names</span>=<span class="string">&quot;spring_topic_queue_well2&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">rabbit:listener-container</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure></div>
<h3 id="524-消息监听器"><a class="markdownIt-Anchor" href="#524-消息监听器">#</a> 5.2.4. 消息监听器</h3>
<h4 id="1队列监听器"><a class="markdownIt-Anchor" href="#1队列监听器">#</a> 1）队列监听器</h4>
<p>创建  <code>spring-rabbitmq-consumer\src\main\java\com\itheima\rabbitmq\listener\SpringQueueListener.java</code></p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SpringQueueListener</span> <span class="keyword">implements</span> <span class="title class_">MessageListener</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onMessage</span><span class="params">(Message message)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">msg</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(message.getBody(), <span class="string">&quot;utf-8&quot;</span>);</span><br><span class="line"></span><br><span class="line">            System.out.printf(<span class="string">&quot;接收路由名称为：%s，路由键为：%s，队列名为：%s的消息：%s \n&quot;</span>,</span><br><span class="line">                    message.getMessageProperties().getReceivedExchange(),</span><br><span class="line">                    message.getMessageProperties().getReceivedRoutingKey(),</span><br><span class="line">                    message.getMessageProperties().getConsumerQueue(),</span><br><span class="line">                    msg);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<h4 id="2广播监听器1"><a class="markdownIt-Anchor" href="#2广播监听器1">#</a> 2）广播监听器 1</h4>
<p>创建  <code>spring-rabbitmq-consumer\src\main\java\com\itheima\rabbitmq\listener\FanoutListener1.java</code></p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FanoutListener1</span> <span class="keyword">implements</span> <span class="title class_">MessageListener</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onMessage</span><span class="params">(Message message)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">msg</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(message.getBody(), <span class="string">&quot;utf-8&quot;</span>);</span><br><span class="line"></span><br><span class="line">            System.out.printf(<span class="string">&quot;广播监听器1：接收路由名称为：%s，路由键为：%s，队列名为：%s的消息：%s \n&quot;</span>,</span><br><span class="line">                    message.getMessageProperties().getReceivedExchange(),</span><br><span class="line">                    message.getMessageProperties().getReceivedRoutingKey(),</span><br><span class="line">                    message.getMessageProperties().getConsumerQueue(),</span><br><span class="line">                    msg);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="3广播监听器2"><a class="markdownIt-Anchor" href="#3广播监听器2">#</a> 3）广播监听器 2</h4>
<p>创建  <code>spring-rabbitmq-consumer\src\main\java\com\itheima\rabbitmq\listener\FanoutListener2.java</code></p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FanoutListener2</span> <span class="keyword">implements</span> <span class="title class_">MessageListener</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onMessage</span><span class="params">(Message message)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">msg</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(message.getBody(), <span class="string">&quot;utf-8&quot;</span>);</span><br><span class="line"></span><br><span class="line">            System.out.printf(<span class="string">&quot;广播监听器2：接收路由名称为：%s，路由键为：%s，队列名为：%s的消息：%s \n&quot;</span>,</span><br><span class="line">                    message.getMessageProperties().getReceivedExchange(),</span><br><span class="line">                    message.getMessageProperties().getReceivedRoutingKey(),</span><br><span class="line">                    message.getMessageProperties().getConsumerQueue(),</span><br><span class="line">                    msg);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<h4 id="4星号通配符监听器"><a class="markdownIt-Anchor" href="#4星号通配符监听器">#</a> 4）星号通配符监听器</h4>
<p>创建  <code>spring-rabbitmq-consumer\src\main\java\com\itheima\rabbitmq\listener\TopicListenerStar.java</code></p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TopicListenerStar</span> <span class="keyword">implements</span> <span class="title class_">MessageListener</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onMessage</span><span class="params">(Message message)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">msg</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(message.getBody(), <span class="string">&quot;utf-8&quot;</span>);</span><br><span class="line"></span><br><span class="line">            System.out.printf(<span class="string">&quot;通配符*监听器：接收路由名称为：%s，路由键为：%s，队列名为：%s的消息：%s \n&quot;</span>,</span><br><span class="line">                    message.getMessageProperties().getReceivedExchange(),</span><br><span class="line">                    message.getMessageProperties().getReceivedRoutingKey(),</span><br><span class="line">                    message.getMessageProperties().getConsumerQueue(),</span><br><span class="line">                    msg);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="5井号通配符监听器"><a class="markdownIt-Anchor" href="#5井号通配符监听器">#</a> 5）井号通配符监听器</h4>
<p>创建  <code>spring-rabbitmq-consumer\src\main\java\com\itheima\rabbitmq\listener\TopicListenerWell.java</code></p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TopicListenerWell</span> <span class="keyword">implements</span> <span class="title class_">MessageListener</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onMessage</span><span class="params">(Message message)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">msg</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(message.getBody(), <span class="string">&quot;utf-8&quot;</span>);</span><br><span class="line"></span><br><span class="line">            System.out.printf(<span class="string">&quot;通配符#监听器：接收路由名称为：%s，路由键为：%s，队列名为：%s的消息：%s \n&quot;</span>,</span><br><span class="line">                    message.getMessageProperties().getReceivedExchange(),</span><br><span class="line">                    message.getMessageProperties().getReceivedRoutingKey(),</span><br><span class="line">                    message.getMessageProperties().getConsumerQueue(),</span><br><span class="line">                    msg);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h4 id="6井号通配符监听器2"><a class="markdownIt-Anchor" href="#6井号通配符监听器2">#</a> 6）井号通配符监听器 2</h4>
<p>创建  <code>spring-rabbitmq-consumer\src\main\java\com\itheima\rabbitmq\listener\TopicListenerWell2.java</code></p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TopicListenerWell2</span> <span class="keyword">implements</span> <span class="title class_">MessageListener</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onMessage</span><span class="params">(Message message)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">msg</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(message.getBody(), <span class="string">&quot;utf-8&quot;</span>);</span><br><span class="line"></span><br><span class="line">            System.out.printf(<span class="string">&quot;通配符#监听器2：接收路由名称为：%s，路由键为：%s，队列名为：%s的消息：%s \n&quot;</span>,</span><br><span class="line">                    message.getMessageProperties().getReceivedExchange(),</span><br><span class="line">                    message.getMessageProperties().getReceivedRoutingKey(),</span><br><span class="line">                    message.getMessageProperties().getConsumerQueue(),</span><br><span class="line">                    msg);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h1 id="6-spring-boot整合rabbitmq"><a class="markdownIt-Anchor" href="#6-spring-boot整合rabbitmq">#</a> 6. Spring Boot 整合 RabbitMQ</h1>
<h2 id="61-简介"><a class="markdownIt-Anchor" href="#61-简介">#</a> 6.1. 简介</h2>
<p>在 Spring 项目中，可以使用 Spring-Rabbit 去操作 RabbitMQ<br>
<a class="link"   target="_blank" rel="noopener" href="https://github.com/spring-projects/spring-amqp" >https://github.com/spring-projects/spring-amqp <i class="fa-regular fa-arrow-up-right-from-square fa-sm"></i></a></p>
<p>尤其是在 spring boot 项目中只需要引入对应的 amqp 启动器依赖即可，方便的使用 RabbitTemplate 发送消息，使用注解接收消息。</p>
<p><em>一般在开发过程中</em>：</p>
<p><strong>生产者工程：</strong></p>
<ol>
<li>
<p>application.yml 文件配置 RabbitMQ 相关信息；</p>
</li>
<li>
<p>在生产者工程中编写配置类，用于创建交换机和队列，并进行绑定</p>
</li>
<li>
<p>注入 RabbitTemplate 对象，通过 RabbitTemplate 对象发送消息到交换机</p>
</li>
</ol>
<p><strong>消费者工程：</strong></p>
<ol>
<li>
<p>application.yml 文件配置 RabbitMQ 相关信息</p>
</li>
<li>
<p>创建消息处理类，用于接收队列中的消息并进行处理</p>
</li>
</ol>
<h2 id="52-搭建生产者工程"><a class="markdownIt-Anchor" href="#52-搭建生产者工程">#</a> 5.2. 搭建生产者工程</h2>
<h3 id="521-创建工程-2"><a class="markdownIt-Anchor" href="#521-创建工程-2">#</a> 5.2.1. 创建工程</h3>
<p>创建生产者工程 springboot-rabbitmq-producer</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1558321303612.png"
                      alt="1556072078816"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1558321417385.png"
                      alt="1556072084653"
                ></p>
<h3 id="522-添加依赖-2"><a class="markdownIt-Anchor" href="#522-添加依赖-2">#</a> 5.2.2. 添加依赖</h3>
<p>修改 pom.xml 文件内容为如下：</p>
<div class="highlight-container" data-rel="Xml"><figure class="iseeu highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.4.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.itheima<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>springboot-rabbitmq-producer<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.0-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-amqp<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br></pre></td></tr></table></figure></div>
<h3 id="523-启动类"><a class="markdownIt-Anchor" href="#523-启动类">#</a> 5.2.3. 启动类</h3>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.SpringApplication;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line"></span><br><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ProducerApplication</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        SpringApplication.run(ProducerApplication.class);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h3 id="524-配置rabbitmq"><a class="markdownIt-Anchor" href="#524-配置rabbitmq">#</a> 5.2.4. 配置 RabbitMQ</h3>
<h4 id="1配置文件"><a class="markdownIt-Anchor" href="#1配置文件">#</a> 1）配置文件</h4>
<p>创建 application.yml，内容如下：</p>
<div class="highlight-container" data-rel="Yml"><figure class="iseeu highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">spring:</span></span><br><span class="line">  <span class="attr">rabbitmq:</span></span><br><span class="line">    <span class="attr">host:</span> <span class="string">localhost</span></span><br><span class="line">    <span class="attr">port:</span> <span class="number">5672</span></span><br><span class="line">    <span class="attr">virtual-host:</span> <span class="string">/itcast</span></span><br><span class="line">    <span class="attr">username:</span> <span class="string">heima</span></span><br><span class="line">    <span class="attr">password:</span> <span class="string">heima</span></span><br></pre></td></tr></table></figure></div>
<h4 id="2绑定交换机和队列"><a class="markdownIt-Anchor" href="#2绑定交换机和队列">#</a> 2）绑定交换机和队列</h4>
<p>创建 RabbitMQ 队列与交换机绑定的配置类 com.itheima.rabbitmq.config.RabbitMQConfig</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.amqp.core.*;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Qualifier;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RabbitMQConfig</span> &#123;</span><br><span class="line">    <span class="comment">//交换机名称</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">ITEM_TOPIC_EXCHANGE</span> <span class="operator">=</span> <span class="string">&quot;item_topic_exchange&quot;</span>;</span><br><span class="line">    <span class="comment">//队列名称</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">ITEM_QUEUE</span> <span class="operator">=</span> <span class="string">&quot;item_queue&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//声明交换机</span></span><br><span class="line">    <span class="meta">@Bean(&quot;itemTopicExchange&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> Exchange <span class="title function_">topicExchange</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> ExchangeBuilder.topicExchange(ITEM_TOPIC_EXCHANGE).durable(<span class="literal">true</span>).build();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//声明队列</span></span><br><span class="line">    <span class="meta">@Bean(&quot;itemQueue&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> Queue <span class="title function_">itemQueue</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> QueueBuilder.durable(ITEM_QUEUE).build();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//绑定队列和交换机</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> Binding <span class="title function_">itemQueueExchange</span><span class="params">(<span class="meta">@Qualifier(&quot;itemQueue&quot;)</span> Queue queue,</span></span><br><span class="line"><span class="params">                                     <span class="meta">@Qualifier(&quot;itemTopicExchange&quot;)</span> Exchange exchange)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> BindingBuilder.bind(queue).to(exchange).with(<span class="string">&quot;item.#&quot;</span>).noargs();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<h2 id="53-搭建消费者工程"><a class="markdownIt-Anchor" href="#53-搭建消费者工程">#</a> 5.3. 搭建消费者工程</h2>
<h3 id="531-创建工程"><a class="markdownIt-Anchor" href="#531-创建工程">#</a> 5.3.1. 创建工程</h3>
<p>创建消费者工程 springboot-rabbitmq-consumer</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1558322109359.png"
                      alt="1556073553841"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1558322192435.png"
                      alt="1556073567786"
                ></p>
<h3 id="532-添加依赖"><a class="markdownIt-Anchor" href="#532-添加依赖">#</a> 5.3.2. 添加依赖</h3>
<p>修改 pom.xml 文件内容为如下：</p>
<div class="highlight-container" data-rel="Xml"><figure class="iseeu highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=<span class="string">&quot;1.0&quot;</span> encoding=<span class="string">&quot;UTF-8&quot;</span>?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">modelVersion</span>&gt;</span>4.0.0<span class="tag">&lt;/<span class="name">modelVersion</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.4.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.itheima<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>springboot-rabbitmq-consumer<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.0-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-amqp<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">project</span>&gt;</span></span><br></pre></td></tr></table></figure></div>
<h3 id="533-启动类"><a class="markdownIt-Anchor" href="#533-启动类">#</a> 5.3.3. 启动类</h3>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.SpringApplication;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line"></span><br><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConsumerApplication</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        SpringApplication.run(ConsumerApplication.class);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<h3 id="534-配置rabbitmq"><a class="markdownIt-Anchor" href="#534-配置rabbitmq">#</a> 5.3.4. 配置 RabbitMQ</h3>
<p>创建 application.yml，内容如下：</p>
<div class="highlight-container" data-rel="Yml"><figure class="iseeu highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">spring:</span></span><br><span class="line">  <span class="attr">rabbitmq:</span></span><br><span class="line">    <span class="attr">host:</span> <span class="string">localhost</span></span><br><span class="line">    <span class="attr">port:</span> <span class="number">5672</span></span><br><span class="line">    <span class="attr">virtual-host:</span> <span class="string">/itcast</span></span><br><span class="line">    <span class="attr">username:</span> <span class="string">heima</span></span><br><span class="line">    <span class="attr">password:</span> <span class="string">heima</span></span><br></pre></td></tr></table></figure></div>
<h3 id="535-消息监听处理类"><a class="markdownIt-Anchor" href="#535-消息监听处理类">#</a> 5.3.5. 消息监听处理类</h3>
<p>编写消息监听器 com.itheima.rabbitmq.listener.MyListener</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq.listener;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.amqp.rabbit.annotation.RabbitListener;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyListener</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 监听某个队列的消息</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> message 接收到的消息</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@RabbitListener(queues = &quot;item_queue&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">myListener1</span><span class="params">(String message)</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;消费者接收到的消息为：&quot;</span> + message);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure></div>
<h2 id="54-测试"><a class="markdownIt-Anchor" href="#54-测试">#</a> 5.4. 测试</h2>
<p>在生产者工程 springboot-rabbitmq-producer 中创建测试类，发送消息：</p>
<div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.itheima.rabbitmq;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.itheima.rabbitmq.config.RabbitMQConfig;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.junit.runner.RunWith;</span><br><span class="line"><span class="keyword">import</span> org.springframework.amqp.rabbit.core.RabbitTemplate;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.test.context.SpringBootTest;</span><br><span class="line"><span class="keyword">import</span> org.springframework.test.context.junit4.SpringRunner;</span><br><span class="line"></span><br><span class="line"><span class="meta">@RunWith(SpringRunner.class)</span></span><br><span class="line"><span class="meta">@SpringBootTest</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RabbitMQTest</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> RabbitTemplate rabbitTemplate;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test</span><span class="params">()</span>&#123;</span><br><span class="line">        rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE, <span class="string">&quot;item.insert&quot;</span>, <span class="string">&quot;商品新增，routing key 为item.insert&quot;</span>);</span><br><span class="line">        rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE, <span class="string">&quot;item.update&quot;</span>, <span class="string">&quot;商品修改，routing key 为item.update&quot;</span>);</span><br><span class="line">        rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE, <span class="string">&quot;item.delete&quot;</span>, <span class="string">&quot;商品删除，routing key 为item.delete&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div>
<p>先运行上述测试程序（交换机和队列才能先被声明和绑定），然后启动消费者；在消费者工程 springboot-rabbitmq-consumer 中控制台查看是否接收到对应消息。</p>
<p>另外；也可以在 RabbitMQ 的管理控制台中查看到交换机与队列的绑定：</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://tuchuang.wenhe9.cn/1556074827222.png"
                      alt="1556074827222"
                ></p>

            </div>

            
                <div class="post-copyright-info">
                    <div class="article-copyright-info-container">
    <ul>
        <li><strong>标题:</strong> RabbitMQ</li>
        <li><strong>作者:</strong> meteor</li>
        <li><strong>创建于:</strong> 2023-06-01 12:37:34</li>
        
            <li>
                <strong>更新于:</strong> 2023-06-05 00:14:13
            </li>
        
        <li>
            <strong>链接:</strong> https://gitee.com/du-jinliang/2023/06/02/RabbitMQ/
        </li>
        <li>
            <strong>版权声明:</strong> 本文章采用 <a class="license" target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">CC BY-NC-SA 4.0</a> 进行许可。
        </li>
    </ul>
</div>

                </div>
            

            
                <ul class="post-tags-box">
                    
                        <li class="tag-item">
                            <a href="/tags/RabbitMQ/">#RabbitMQ</a>&nbsp;
                        </li>
                    
                </ul>
            

            

            
                <div class="article-nav">
                    
                        <div class="article-prev">
                            <a class="prev"
                            rel="prev"
                            href="/2023/06/06/Docker/"
                            >
                                <span class="left arrow-icon flex-center">
                                    <i class="fa-solid fa-chevron-left"></i>
                                </span>
                                <span class="title flex-center">
                                    <span class="post-nav-title-item">Docker</span>
                                    <span class="post-nav-item">上一篇</span>
                                </span>
                            </a>
                        </div>
                    
                    
                        <div class="article-next">
                            <a class="next"
                            rel="next"
                            href="/2023/06/02/Android/"
                            >
                                <span class="title flex-center">
                                    <span class="post-nav-title-item">Android</span>
                                    <span class="post-nav-item">下一篇</span>
                                </span>
                                <span class="right arrow-icon flex-center">
                                    <i class="fa-solid fa-chevron-right"></i>
                                </span>
                            </a>
                        </div>
                    
                </div>
            


            
                <div class="comment-container">
                    <div class="comments-container">
    <div id="comment-anchor"></div>
    <div class="comment-area-title">
        <i class="fa-solid fa-comments"></i>&nbsp;评论
    </div>
    

        
            
    <div id="gitalk-container"></div>
    <script data-pjax
            src="//cdn.jsdelivr.net/npm/gitalk/dist/gitalk.min.js"></script>
    <script data-pjax>

        function loadGitalk() {
            let __gitalk__pathname = decodeURI(location.pathname);
            const __gitalk__pathnameLength = __gitalk__pathname.length;
            const __gitalk__pathnameMaxLength = 50;
            if (__gitalk__pathnameLength > __gitalk__pathnameMaxLength) {
                __gitalk__pathname = __gitalk__pathname.substring(0, __gitalk__pathnameMaxLength - 3) + '...';
            }

            try {
                Gitalk && new Gitalk({
                    clientID: '55bad54a77b7e60ad62d',
                    clientSecret: '1031c81500c6be06e338087cb7b713f2d0201b46',
                    repo: 'wait-you.github.io',
                    owner: 'wait-you',
                    admin: ['wait-you'],
                    id: 'comment',
                    language: 'zh-CN'
                }).render('gitalk-container');

            } catch (e) {
                window.Gitalk = null;
            }
        }

        if ('true') {
            const loadGitalkTimeout = setTimeout(() => {
                loadGitalk();
                clearTimeout(loadGitalkTimeout);
            }, 1000);
        } else {
            window.addEventListener('DOMContentLoaded', loadGitalk);
        }
    </script>



        
    
</div>

                </div>
            
        </div>

        
            <div class="toc-content-container">
                <div class="post-toc-wrap">
    <div class="post-toc">
        <div class="toc-title">此页目录</div>
        <div class="page-title">RabbitMQ</div>
        <ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#1-%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6%E6%A6%82%E8%BF%B0"><span class="nav-text"> 1. 消息中间件概述</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#11-%E4%BB%80%E4%B9%88%E6%98%AF%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6"><span class="nav-text"> 1.1. 什么是消息中间件</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#12-amqp-%E5%92%8C-jms"><span class="nav-text"> 1.2. AMQP 和 JMS</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#121-amqp"><span class="nav-text"> 1.2.1. AMQP</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#122-jms"><span class="nav-text"> 1.2.2. JMS</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#123-amqp-%E4%B8%8E-jms-%E5%8C%BA%E5%88%AB"><span class="nav-text"> 1.2.3. AMQP 与 JMS 区别</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#13-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E4%BA%A7%E5%93%81"><span class="nav-text"> 1.3. 消息队列产品</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#14-rabbitmq"><span class="nav-text"> 1.4. RabbitMQ</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#2-%E5%AE%89%E8%A3%85%E5%8F%8A%E9%85%8D%E7%BD%AErabbitmq"><span class="nav-text"> 2. 安装及配置 RabbitMQ</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#3-rabbitmq%E5%85%A5%E9%97%A8"><span class="nav-text"> 3. RabbitMQ 入门</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#31-%E6%90%AD%E5%BB%BA%E7%A4%BA%E4%BE%8B%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 3.1. 搭建示例工程</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#311-%E5%88%9B%E5%BB%BA%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 3.1.1. 创建工程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#312-%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96"><span class="nav-text"> 3.1.2. 添加依赖</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#32-%E7%BC%96%E5%86%99%E7%94%9F%E4%BA%A7%E8%80%85"><span class="nav-text"> 3.2. 编写生产者</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#33-%E7%BC%96%E5%86%99%E6%B6%88%E8%B4%B9%E8%80%85"><span class="nav-text"> 3.3. 编写消费者</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#34-%E5%B0%8F%E7%BB%93"><span class="nav-text"> 3.4. 小结</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#4-amqp"><span class="nav-text"> 4. AMQP</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#41-%E7%9B%B8%E5%85%B3%E6%A6%82%E5%BF%B5%E4%BB%8B%E7%BB%8D"><span class="nav-text"> 4.1. 相关概念介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#42-rabbitmq%E8%BF%90%E8%BD%AC%E6%B5%81%E7%A8%8B"><span class="nav-text"> 4.2. RabbitMQ 运转流程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#43-%E7%94%9F%E4%BA%A7%E8%80%85%E6%B5%81%E8%BD%AC%E8%BF%87%E7%A8%8B%E8%AF%B4%E6%98%8E"><span class="nav-text"> 4.3. 生产者流转过程说明</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#44-%E6%B6%88%E8%B4%B9%E8%80%85%E6%B5%81%E8%BD%AC%E8%BF%87%E7%A8%8B%E8%AF%B4%E6%98%8E"><span class="nav-text"> 4.4. 消费者流转过程说明</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#5-rabbitmq%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F"><span class="nav-text"> 5. RabbitMQ 工作模式</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#41-work-queues%E5%B7%A5%E4%BD%9C%E9%98%9F%E5%88%97%E6%A8%A1%E5%BC%8F"><span class="nav-text"> 4.1. Work queues 工作队列模式</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#411-%E6%A8%A1%E5%BC%8F%E8%AF%B4%E6%98%8E"><span class="nav-text"> 4.1.1. 模式说明</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#412-%E4%BB%A3%E7%A0%81"><span class="nav-text"> 4.1.2. 代码</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#413-%E6%B5%8B%E8%AF%95"><span class="nav-text"> 4.1.3. 测试</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#414-%E5%B0%8F%E7%BB%93"><span class="nav-text"> 4.1.4. 小结</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#42-%E8%AE%A2%E9%98%85%E6%A8%A1%E5%BC%8F%E7%B1%BB%E5%9E%8B"><span class="nav-text"> 4.2. 订阅模式类型</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#43-publishsubscribe%E5%8F%91%E5%B8%83%E4%B8%8E%E8%AE%A2%E9%98%85%E6%A8%A1%E5%BC%8F"><span class="nav-text"> 4.3. Publish&#x2F;Subscribe 发布与订阅模式</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#431-%E6%A8%A1%E5%BC%8F%E8%AF%B4%E6%98%8E"><span class="nav-text"> 4.3.1. 模式说明</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#432-%E4%BB%A3%E7%A0%81"><span class="nav-text"> 4.3.2. 代码</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#433-%E6%B5%8B%E8%AF%95"><span class="nav-text"> 4.3.3. 测试</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#434-%E5%B0%8F%E7%BB%93"><span class="nav-text"> 4.3.4. 小结</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#44-routing%E8%B7%AF%E7%94%B1%E6%A8%A1%E5%BC%8F"><span class="nav-text"> 4.4. Routing 路由模式</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#441-%E6%A8%A1%E5%BC%8F%E8%AF%B4%E6%98%8E"><span class="nav-text"> 4.4.1. 模式说明</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#442-%E4%BB%A3%E7%A0%81"><span class="nav-text"> 4.4.2. 代码</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#443-%E6%B5%8B%E8%AF%95"><span class="nav-text"> 4.4.3. 测试</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#444-%E5%B0%8F%E7%BB%93"><span class="nav-text"> 4.4.4. 小结</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#45-topics%E9%80%9A%E9%85%8D%E7%AC%A6%E6%A8%A1%E5%BC%8F"><span class="nav-text"> 4.5. Topics 通配符模式</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#451-%E6%A8%A1%E5%BC%8F%E8%AF%B4%E6%98%8E"><span class="nav-text"> 4.5.1. 模式说明</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#452-%E4%BB%A3%E7%A0%81"><span class="nav-text"> 4.5.2. 代码</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#453-%E6%B5%8B%E8%AF%95"><span class="nav-text"> 4.5.3. 测试</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#454-%E5%B0%8F%E7%BB%93"><span class="nav-text"> 4.5.4. 小结</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#46-%E6%A8%A1%E5%BC%8F%E6%80%BB%E7%BB%93"><span class="nav-text"> 4.6. 模式总结</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#5-spring-%E6%95%B4%E5%90%88rabbitmq"><span class="nav-text"> 5. Spring 整合 RabbitMQ</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#51-%E6%90%AD%E5%BB%BA%E7%94%9F%E4%BA%A7%E8%80%85%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 5.1. 搭建生产者工程</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#511-%E5%88%9B%E5%BB%BA%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 5.1.1. 创建工程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#512-%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96"><span class="nav-text"> 5.1.2. 添加依赖</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#513-%E9%85%8D%E7%BD%AE%E6%95%B4%E5%90%88"><span class="nav-text"> 5.1.3. 配置整合</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#514-%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF"><span class="nav-text"> 5.1.4. 发送消息</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#52-%E6%90%AD%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 5.2. 搭建消费者工程</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#521-%E5%88%9B%E5%BB%BA%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 5.2.1. 创建工程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#522-%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96"><span class="nav-text"> 5.2.2. 添加依赖</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#523-%E9%85%8D%E7%BD%AE%E6%95%B4%E5%90%88"><span class="nav-text"> 5.2.3. 配置整合</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#524-%E6%B6%88%E6%81%AF%E7%9B%91%E5%90%AC%E5%99%A8"><span class="nav-text"> 5.2.4. 消息监听器</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#6-spring-boot%E6%95%B4%E5%90%88rabbitmq"><span class="nav-text"> 6. Spring Boot 整合 RabbitMQ</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#61-%E7%AE%80%E4%BB%8B"><span class="nav-text"> 6.1. 简介</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#52-%E6%90%AD%E5%BB%BA%E7%94%9F%E4%BA%A7%E8%80%85%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 5.2. 搭建生产者工程</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#521-%E5%88%9B%E5%BB%BA%E5%B7%A5%E7%A8%8B-2"><span class="nav-text"> 5.2.1. 创建工程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#522-%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96-2"><span class="nav-text"> 5.2.2. 添加依赖</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#523-%E5%90%AF%E5%8A%A8%E7%B1%BB"><span class="nav-text"> 5.2.3. 启动类</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#524-%E9%85%8D%E7%BD%AErabbitmq"><span class="nav-text"> 5.2.4. 配置 RabbitMQ</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#53-%E6%90%AD%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 5.3. 搭建消费者工程</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#531-%E5%88%9B%E5%BB%BA%E5%B7%A5%E7%A8%8B"><span class="nav-text"> 5.3.1. 创建工程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#532-%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96"><span class="nav-text"> 5.3.2. 添加依赖</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#533-%E5%90%AF%E5%8A%A8%E7%B1%BB"><span class="nav-text"> 5.3.3. 启动类</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#534-%E9%85%8D%E7%BD%AErabbitmq"><span class="nav-text"> 5.3.4. 配置 RabbitMQ</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#535-%E6%B6%88%E6%81%AF%E7%9B%91%E5%90%AC%E5%A4%84%E7%90%86%E7%B1%BB"><span class="nav-text"> 5.3.5. 消息监听处理类</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#54-%E6%B5%8B%E8%AF%95"><span class="nav-text"> 5.4. 测试</span></a></li></ol></li></ol>

    </div>
</div>
            </div>
        
    </div>
</div>


                

            </div>
            
            

        </div>

        <div class="main-content-footer">
            <footer class="footer">
    <div class="info-container">
        <div class="copyright-info">
            &copy;
            
              <span>2022</span>
              -
            
            2023&nbsp;&nbsp;<i class="fa-solid fa-heart fa-beat" style="--fa-animation-duration: 0.5s; color: #f54545"></i>&nbsp;&nbsp;<a href="/">meteor</a>
        </div>
        
            <script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
            <div class="website-count info-item">
                
                    <span id="busuanzi_container_site_uv" class="busuanzi_container_site_uv">
                        访问人数&nbsp;<span id="busuanzi_value_site_uv" class="busuanzi_value_site_uv"></span>
                    </span>
                
                
                    <span id="busuanzi_container_site_pv" class="busuanzi_container_site_pv">
                        总访问量&nbsp;<span id="busuanzi_value_site_pv" class="busuanzi_value_site_pv"></span>
                    </span>
                
            </div>
        
        <div class="theme-info info-item">
            <span class="powered-by-container">由 <?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1rem" height="1rem" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"><path fill="#0E83CD" d="M256.4,25.8l-200,115.5L56,371.5l199.6,114.7l200-115.5l0.4-230.2L256.4,25.8z M349,354.6l-18.4,10.7l-18.6-11V275H200v79.6l-18.4,10.7l-18.6-11v-197l18.5-10.6l18.5,10.8V237h112v-79.6l18.5-10.6l18.5,10.8V354.6z"/></svg><a target="_blank" href="https://hexo.io">Hexo</a> 驱动</span>
                <br>
            <span class="theme-version-container">主题&nbsp;<a class="theme-version" target="_blank" href="https://github.com/EvanNotFound/hexo-theme-redefine">Redefine v2.1.4</a>
        </div>
        
            <div class="icp-info info-item"><a target="_blank" rel="nofollow" href="
                
                    beian.miit.gov.cn
                
                ">冀ICP备20010108号</a></div>
        
        
        
            <div id="start_div" style="display:none">
                2022/8/17 11:45:14
            </div>
            <div>
                博客已运行 <span class="odometer" id="runtime_days" ></span> 天 <span class="odometer" id="runtime_hours"></span> 小时 <span class="odometer" id="runtime_minutes"></span> 分钟 <span class="odometer" id="runtime_seconds"></span> 秒
            </div>
        
        
        
            <script async data-pjax>
                try {
                    function odometer_init() {
                    const elements = document.querySelectorAll('.odometer');
                    elements.forEach(el => {
                        new Odometer({
                            el,
                            format: '( ddd).dd',
                            duration: 200
                        });
                    });
                    }
                    odometer_init();
                } catch (error) {}
            </script>
        
        
        
    </div>  
</footer>
        </div>
    </div>

    
        <div class="post-tools">
            <div class="post-tools-container">
    <ul class="article-tools-list">
        <!-- TOC aside toggle -->
        
            <li class="right-bottom-tools page-aside-toggle">
                <i class="fa-regular fa-outdent"></i>
            </li>
        

        <!-- go comment -->
        
            <li class="go-comment">
                <i class="fa-regular fa-comments"></i>
            </li>
        
    </ul>
</div>

        </div>
    

    <div class="right-side-tools-container">
        <div class="side-tools-container">
    <ul class="hidden-tools-list">
        <li class="right-bottom-tools tool-font-adjust-plus flex-center">
            <i class="fa-regular fa-magnifying-glass-plus"></i>
        </li>

        <li class="right-bottom-tools tool-font-adjust-minus flex-center">
            <i class="fa-regular fa-magnifying-glass-minus"></i>
        </li>

        <li class="right-bottom-tools tool-expand-width flex-center">
            <i class="fa-regular fa-expand"></i>
        </li>

        <li class="right-bottom-tools tool-dark-light-toggle flex-center">
            <i class="fa-regular fa-moon"></i>
        </li>

        <!-- rss -->
        

        

        <li class="right-bottom-tools tool-scroll-to-bottom flex-center">
            <i class="fa-regular fa-arrow-down"></i>
        </li>
    </ul>

    <ul class="visible-tools-list">
        <li class="right-bottom-tools toggle-tools-list flex-center">
            <i class="fa-regular fa-cog fa-spin"></i>
        </li>
        
            <li class="right-bottom-tools tool-scroll-to-top flex-center">
                <i class="arrow-up fas fa-arrow-up"></i>
                <span class="percent"></span>
            </li>
        
        
    </ul>
</div>

    </div>

    <div class="image-viewer-container">
    <img src="">
</div>


    


</main>




<script src="/js/utils.js"></script>

<script src="/js/main.js"></script>

<script src="/js/layouts/navbarShrink.js"></script>

<script src="/js/tools/scrollTopBottom.js"></script>

<script src="/js/tools/lightDarkSwitch.js"></script>





    
<script src="/js/tools/codeBlock.js"></script>




    
<script src="/js/layouts/lazyload.js"></script>




    
<script src="/js/tools/runtime.js"></script>

    
<script src="/js/layouts/odometer.min.js"></script>

    
<link rel="stylesheet" href="/assets/odometer-theme-minimal.css">




  
<script src="/js/libs/Typed.min.js"></script>

  
<script src="/js/plugins/typed.js"></script>







<div class="post-scripts pjax">
    
        
<script src="/js/tools/tocToggle.js"></script>

<script src="/js/libs/anime.min.js"></script>

<script src="/js/layouts/toc.js"></script>

<script src="/js/plugins/tabs.js"></script>

    
</div>


    
<script src="/js/libs/pjax.min.js"></script>

<script>
    window.addEventListener('DOMContentLoaded', () => {
        window.pjax = new Pjax({
            selectors: [
                'head title',
                '.page-container',
                '.pjax',
            ],
            history: true,
            debug: false,
            cacheBust: false,
            timeout: 0,
            analytics: false,
            currentUrlFullReload: false,
            scrollRestoration: false,
            // scrollTo: true,
        });

        document.addEventListener('pjax:send', () => {
            Global.utils.pjaxProgressBarStart();
        });

        document.addEventListener('pjax:complete', () => {
            Global.utils.pjaxProgressBarEnd();
            window.pjax.executeScripts(document.querySelectorAll('script[data-pjax], .pjax script'));
            Global.refresh();
        });
    });
</script>




</body>
</html>
